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