1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
4 use crate::AppLaunchContext;
5 use crate::DesktopAppInfo;
6 use glib::object::IsA;
7 use glib::translate::*;
8 #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
9 use glib::Error;
10 use glib::GString;
11 #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
12 use std::boxed::Box as Box_;
13 #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
14 use std::ptr;
15 
16 #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
17 use std::os::unix::io::AsRawFd;
18 
19 impl DesktopAppInfo {
20     #[doc(alias = "g_desktop_app_info_search")]
search(search_string: &str) -> Vec<Vec<GString>>21     pub fn search(search_string: &str) -> Vec<Vec<GString>> {
22         unsafe {
23             let out = ffi::g_desktop_app_info_search(search_string.to_glib_none().0);
24 
25             if out.is_null() {
26                 return Vec::new();
27             }
28 
29             let mut ret = Vec::new();
30             let mut it = 0;
31             loop {
32                 let tmp: *mut *mut libc::c_char = *out.offset(it);
33 
34                 if tmp.is_null() {
35                     break;
36                 }
37                 let v: Vec<GString> = FromGlibPtrContainer::from_glib_full(tmp);
38                 ret.push(v);
39                 it += 1;
40             }
41 
42             glib::ffi::g_free(out as *mut libc::c_void);
43             ret
44         }
45     }
46 }
47 
48 pub trait DesktopAppInfoExtManual {
49     #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
50     #[cfg_attr(feature = "dox", doc(cfg(all(feature = "v2_58", unix))))]
51     #[doc(alias = "g_desktop_app_info_launch_uris_as_manager_with_fds")]
launch_uris_as_manager_with_fds< P: IsA<AppLaunchContext>, T: AsRawFd, U: AsRawFd, V: AsRawFd, >( &self, uris: &[&str], launch_context: Option<&P>, spawn_flags: glib::SpawnFlags, user_setup: Option<Box_<dyn FnOnce() + 'static>>, pid_callback: Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))>, stdin_fd: &mut T, stdout_fd: &mut U, stderr_fd: &mut V, ) -> Result<(), Error>52     fn launch_uris_as_manager_with_fds<
53         P: IsA<AppLaunchContext>,
54         T: AsRawFd,
55         U: AsRawFd,
56         V: AsRawFd,
57     >(
58         &self,
59         uris: &[&str],
60         launch_context: Option<&P>,
61         spawn_flags: glib::SpawnFlags,
62         user_setup: Option<Box_<dyn FnOnce() + 'static>>,
63         pid_callback: Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))>,
64         stdin_fd: &mut T,
65         stdout_fd: &mut U,
66         stderr_fd: &mut V,
67     ) -> Result<(), Error>;
68 }
69 
70 impl<O: IsA<DesktopAppInfo>> DesktopAppInfoExtManual for O {
71     #[cfg(any(all(feature = "v2_58", unix), all(unix, feature = "dox")))]
72     #[cfg_attr(feature = "dox", doc(cfg(all(feature = "v2_58", unix))))]
launch_uris_as_manager_with_fds< P: IsA<AppLaunchContext>, T: AsRawFd, U: AsRawFd, V: AsRawFd, >( &self, uris: &[&str], launch_context: Option<&P>, spawn_flags: glib::SpawnFlags, user_setup: Option<Box_<dyn FnOnce() + 'static>>, pid_callback: Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))>, stdin_fd: &mut T, stdout_fd: &mut U, stderr_fd: &mut V, ) -> Result<(), Error>73     fn launch_uris_as_manager_with_fds<
74         P: IsA<AppLaunchContext>,
75         T: AsRawFd,
76         U: AsRawFd,
77         V: AsRawFd,
78     >(
79         &self,
80         uris: &[&str],
81         launch_context: Option<&P>,
82         spawn_flags: glib::SpawnFlags,
83         user_setup: Option<Box_<dyn FnOnce() + 'static>>,
84         pid_callback: Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))>,
85         stdin_fd: &mut T,
86         stdout_fd: &mut U,
87         stderr_fd: &mut V,
88     ) -> Result<(), Error> {
89         let user_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(user_setup);
90         unsafe extern "C" fn user_setup_func<P: IsA<AppLaunchContext>>(
91             user_data: glib::ffi::gpointer,
92         ) {
93             let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
94                 Box_::from_raw(user_data as *mut _);
95             let callback = (*callback).expect("cannot get closure...");
96             callback()
97         }
98         let user_setup = if user_setup_data.is_some() {
99             Some(user_setup_func::<P> as _)
100         } else {
101             None
102         };
103         let pid_callback_data: Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))> = pid_callback;
104         unsafe extern "C" fn pid_callback_func<P: IsA<AppLaunchContext>>(
105             appinfo: *mut ffi::GDesktopAppInfo,
106             pid: glib::ffi::GPid,
107             user_data: glib::ffi::gpointer,
108         ) {
109             let appinfo = from_glib_borrow(appinfo);
110             let pid = from_glib(pid);
111             let callback: *mut Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))> =
112                 user_data as *const _ as usize
113                     as *mut Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))>;
114             if let Some(ref mut callback) = *callback {
115                 callback(&appinfo, pid)
116             } else {
117                 panic!("cannot get closure...")
118             };
119         }
120         let pid_callback = if pid_callback_data.is_some() {
121             Some(pid_callback_func::<P> as _)
122         } else {
123             None
124         };
125         let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = user_setup_data;
126         let super_callback1: &Option<&mut dyn (FnMut(&DesktopAppInfo, glib::Pid))> =
127             &pid_callback_data;
128         unsafe {
129             let mut error = ptr::null_mut();
130             let _ = ffi::g_desktop_app_info_launch_uris_as_manager_with_fds(
131                 self.as_ref().to_glib_none().0,
132                 uris.to_glib_none().0,
133                 launch_context.map(|p| p.as_ref()).to_glib_none().0,
134                 spawn_flags.into_glib(),
135                 user_setup,
136                 Box_::into_raw(super_callback0) as *mut _,
137                 pid_callback,
138                 super_callback1 as *const _ as usize as *mut _,
139                 stdin_fd.as_raw_fd(),
140                 stdout_fd.as_raw_fd(),
141                 stderr_fd.as_raw_fd(),
142                 &mut error,
143             );
144             if error.is_null() {
145                 Ok(())
146             } else {
147                 Err(from_glib_full(error))
148             }
149         }
150     }
151 }
152