1use gio_sys;
6use glib;
7use glib::object::Cast;
8use glib::object::IsA;
9use glib::signal::connect_raw;
10use glib::signal::SignalHandlerId;
11use glib::translate::*;
12use glib::StaticType;
13use glib::Value;
14use glib_sys;
15use gobject_sys;
16use std::boxed::Box as Box_;
17use std::fmt;
18use std::mem::transmute;
19use std::ptr;
20use Cancellable;
21use Error;
22use Socket;
23use SocketAddress;
24use SocketConnection;
25#[cfg(any(feature = "v2_46", feature = "dox"))]
26use SocketListenerEvent;
27use SocketProtocol;
28use SocketType;
29
30glib_wrapper! {
31 pub struct SocketListener(Object<gio_sys::GSocketListener, gio_sys::GSocketListenerClass, SocketListenerClass>);
32
33 match fn {
34 get_type => || gio_sys::g_socket_listener_get_type(),
35 }
36}
37
38impl SocketListener {
39 pub fn new() -> SocketListener {
40 unsafe { from_glib_full(gio_sys::g_socket_listener_new()) }
41 }
42}
43
44impl Default for SocketListener {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50pub const NONE_SOCKET_LISTENER: Option<&SocketListener> = None;
51
52pub trait SocketListenerExt: 'static {
53 fn accept<P: IsA<Cancellable>>(
54 &self,
55 cancellable: Option<&P>,
56 ) -> Result<(SocketConnection, Option<glib::Object>), Error>;
57
58 fn accept_socket<P: IsA<Cancellable>>(
59 &self,
60 cancellable: Option<&P>,
61 ) -> Result<(Socket, Option<glib::Object>), Error>;
62
63 fn add_address<P: IsA<SocketAddress>, Q: IsA<glib::Object>>(
64 &self,
65 address: &P,
66 type_: SocketType,
67 protocol: SocketProtocol,
68 source_object: Option<&Q>,
69 ) -> Result<SocketAddress, Error>;
70
71 fn add_any_inet_port<P: IsA<glib::Object>>(
72 &self,
73 source_object: Option<&P>,
74 ) -> Result<u16, Error>;
75
76 fn add_inet_port<P: IsA<glib::Object>>(
77 &self,
78 port: u16,
79 source_object: Option<&P>,
80 ) -> Result<(), Error>;
81
82 fn add_socket<P: IsA<Socket>, Q: IsA<glib::Object>>(
83 &self,
84 socket: &P,
85 source_object: Option<&Q>,
86 ) -> Result<(), Error>;
87
88 fn close(&self);
89
90 fn set_backlog(&self, listen_backlog: i32);
91
92 fn get_property_listen_backlog(&self) -> i32;
93
94 fn set_property_listen_backlog(&self, listen_backlog: i32);
95
96 #[cfg(any(feature = "v2_46", feature = "dox"))]
97 fn connect_event<F: Fn(&Self, SocketListenerEvent, &Socket) + 'static>(
98 &self,
99 f: F,
100 ) -> SignalHandlerId;
101
102 fn connect_property_listen_backlog_notify<F: Fn(&Self) + 'static>(
103 &self,
104 f: F,
105 ) -> SignalHandlerId;
106}
107
108impl<O: IsA<SocketListener>> SocketListenerExt for O {
109 fn accept<P: IsA<Cancellable>>(
110 &self,
111 cancellable: Option<&P>,
112 ) -> Result<(SocketConnection, Option<glib::Object>), Error> {
113 unsafe {
114 let mut source_object = ptr::null_mut();
115 let mut error = ptr::null_mut();
116 let ret = gio_sys::g_socket_listener_accept(
117 self.as_ref().to_glib_none().0,
118 &mut source_object,
119 cancellable.map(|p| p.as_ref()).to_glib_none().0,
120 &mut error,
121 );
122 if error.is_null() {
123 Ok((from_glib_full(ret), from_glib_none(source_object)))
124 } else {
125 Err(from_glib_full(error))
126 }
127 }
128 }
129
130 fn accept_socket<P: IsA<Cancellable>>(
131 &self,
132 cancellable: Option<&P>,
133 ) -> Result<(Socket, Option<glib::Object>), Error> {
134 unsafe {
135 let mut source_object = ptr::null_mut();
136 let mut error = ptr::null_mut();
137 let ret = gio_sys::g_socket_listener_accept_socket(
138 self.as_ref().to_glib_none().0,
139 &mut source_object,
140 cancellable.map(|p| p.as_ref()).to_glib_none().0,
141 &mut error,
142 );
143 if error.is_null() {
144 Ok((from_glib_full(ret), from_glib_none(source_object)))
145 } else {
146 Err(from_glib_full(error))
147 }
148 }
149 }
150
151 fn add_address<P: IsA<SocketAddress>, Q: IsA<glib::Object>>(
152 &self,
153 address: &P,
154 type_: SocketType,
155 protocol: SocketProtocol,
156 source_object: Option<&Q>,
157 ) -> Result<SocketAddress, Error> {
158 unsafe {
159 let mut effective_address = ptr::null_mut();
160 let mut error = ptr::null_mut();
161 let _ = gio_sys::g_socket_listener_add_address(
162 self.as_ref().to_glib_none().0,
163 address.as_ref().to_glib_none().0,
164 type_.to_glib(),
165 protocol.to_glib(),
166 source_object.map(|p| p.as_ref()).to_glib_none().0,
167 &mut effective_address,
168 &mut error,
169 );
170 if error.is_null() {
171 Ok(from_glib_full(effective_address))
172 } else {
173 Err(from_glib_full(error))
174 }
175 }
176 }
177
178 fn add_any_inet_port<P: IsA<glib::Object>>(
179 &self,
180 source_object: Option<&P>,
181 ) -> Result<u16, Error> {
182 unsafe {
183 let mut error = ptr::null_mut();
184 let ret = gio_sys::g_socket_listener_add_any_inet_port(
185 self.as_ref().to_glib_none().0,
186 source_object.map(|p| p.as_ref()).to_glib_none().0,
187 &mut error,
188 );
189 if error.is_null() {
190 Ok(ret)
191 } else {
192 Err(from_glib_full(error))
193 }
194 }
195 }
196
197 fn add_inet_port<P: IsA<glib::Object>>(
198 &self,
199 port: u16,
200 source_object: Option<&P>,
201 ) -> Result<(), Error> {
202 unsafe {
203 let mut error = ptr::null_mut();
204 let _ = gio_sys::g_socket_listener_add_inet_port(
205 self.as_ref().to_glib_none().0,
206 port,
207 source_object.map(|p| p.as_ref()).to_glib_none().0,
208 &mut error,
209 );
210 if error.is_null() {
211 Ok(())
212 } else {
213 Err(from_glib_full(error))
214 }
215 }
216 }
217
218 fn add_socket<P: IsA<Socket>, Q: IsA<glib::Object>>(
219 &self,
220 socket: &P,
221 source_object: Option<&Q>,
222 ) -> Result<(), Error> {
223 unsafe {
224 let mut error = ptr::null_mut();
225 let _ = gio_sys::g_socket_listener_add_socket(
226 self.as_ref().to_glib_none().0,
227 socket.as_ref().to_glib_none().0,
228 source_object.map(|p| p.as_ref()).to_glib_none().0,
229 &mut error,
230 );
231 if error.is_null() {
232 Ok(())
233 } else {
234 Err(from_glib_full(error))
235 }
236 }
237 }
238
239 fn close(&self) {
240 unsafe {
241 gio_sys::g_socket_listener_close(self.as_ref().to_glib_none().0);
242 }
243 }
244
245 fn set_backlog(&self, listen_backlog: i32) {
246 unsafe {
247 gio_sys::g_socket_listener_set_backlog(self.as_ref().to_glib_none().0, listen_backlog);
248 }
249 }
250
251 fn get_property_listen_backlog(&self) -> i32 {
252 unsafe {
253 let mut value = Value::from_type(<i32 as StaticType>::static_type());
254 gobject_sys::g_object_get_property(
255 self.to_glib_none().0 as *mut gobject_sys::GObject,
256 b"listen-backlog\0".as_ptr() as *const _,
257 value.to_glib_none_mut().0,
258 );
259 value.get().unwrap()
260 }
261 }
262
263 fn set_property_listen_backlog(&self, listen_backlog: i32) {
264 unsafe {
265 gobject_sys::g_object_set_property(
266 self.to_glib_none().0 as *mut gobject_sys::GObject,
267 b"listen-backlog\0".as_ptr() as *const _,
268 Value::from(&listen_backlog).to_glib_none().0,
269 );
270 }
271 }
272
273 #[cfg(any(feature = "v2_46", feature = "dox"))]
274 fn connect_event<F: Fn(&Self, SocketListenerEvent, &Socket) + 'static>(
275 &self,
276 f: F,
277 ) -> SignalHandlerId {
278 unsafe extern "C" fn event_trampoline<
279 P,
280 F: Fn(&P, SocketListenerEvent, &Socket) + 'static,
281 >(
282 this: *mut gio_sys::GSocketListener,
283 event: gio_sys::GSocketListenerEvent,
284 socket: *mut gio_sys::GSocket,
285 f: glib_sys::gpointer,
286 ) where
287 P: IsA<SocketListener>,
288 {
289 let f: &F = &*(f as *const F);
290 f(
291 &SocketListener::from_glib_borrow(this).unsafe_cast(),
292 from_glib(event),
293 &from_glib_borrow(socket),
294 )
295 }
296 unsafe {
297 let f: Box_<F> = Box_::new(f);
298 connect_raw(
299 self.as_ptr() as *mut _,
300 b"event\0".as_ptr() as *const _,
301 Some(transmute(event_trampoline::<Self, F> as usize)),
302 Box_::into_raw(f),
303 )
304 }
305 }
306
307 fn connect_property_listen_backlog_notify<F: Fn(&Self) + 'static>(
308 &self,
309 f: F,
310 ) -> SignalHandlerId {
311 unsafe extern "C" fn notify_listen_backlog_trampoline<P, F: Fn(&P) + 'static>(
312 this: *mut gio_sys::GSocketListener,
313 _param_spec: glib_sys::gpointer,
314 f: glib_sys::gpointer,
315 ) where
316 P: IsA<SocketListener>,
317 {
318 let f: &F = &*(f as *const F);
319 f(&SocketListener::from_glib_borrow(this).unsafe_cast())
320 }
321 unsafe {
322 let f: Box_<F> = Box_::new(f);
323 connect_raw(
324 self.as_ptr() as *mut _,
325 b"notify::listen-backlog\0".as_ptr() as *const _,
326 Some(transmute(
327 notify_listen_backlog_trampoline::<Self, F> as usize,
328 )),
329 Box_::into_raw(f),
330 )
331 }
332 }
333}
334
335impl fmt::Display for SocketListener {
336 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
337 write!(f, "SocketListener")
338 }
339}