1 use super::*;
2 
3 pub type ClientMsgPayload = [c_long; 5];
4 
5 impl XConnection {
send_event<T: Into<ffi::XEvent>>( &self, target_window: c_ulong, event_mask: Option<c_long>, event: T, ) -> Flusher6     pub fn send_event<T: Into<ffi::XEvent>>(
7         &self,
8         target_window: c_ulong,
9         event_mask: Option<c_long>,
10         event: T,
11     ) -> Flusher {
12         let event_mask = event_mask.unwrap_or(ffi::NoEventMask);
13         unsafe {
14             (self.xlib.XSendEvent)(
15                 self.display,
16                 target_window,
17                 ffi::False,
18                 event_mask,
19                 &mut event.into(),
20             );
21         }
22         Flusher::new(self)
23     }
24 
send_client_msg( &self, window: c_ulong, target_window: c_ulong, message_type: ffi::Atom, event_mask: Option<c_long>, data: ClientMsgPayload, ) -> Flusher25     pub fn send_client_msg(
26         &self,
27         window: c_ulong,        // The window this is "about"; not necessarily this window
28         target_window: c_ulong, // The window we're sending to
29         message_type: ffi::Atom,
30         event_mask: Option<c_long>,
31         data: ClientMsgPayload,
32     ) -> Flusher {
33         let mut event: ffi::XClientMessageEvent = unsafe { mem::uninitialized() };
34         event.type_ = ffi::ClientMessage;
35         event.display = self.display;
36         event.window = window;
37         event.message_type = message_type;
38         event.format = c_long::FORMAT as c_int;
39         event.data = unsafe { mem::transmute(data) };
40         self.send_event(target_window, event_mask, event)
41     }
42 
43     // Prepare yourself for the ultimate in unsafety!
44     // You should favor `send_client_msg` whenever possible, but some protocols (i.e. startup notification) require you
45     // to send more than one message worth of data.
send_client_msg_multi<T: Formattable>( &self, window: c_ulong, target_window: c_ulong, message_type: ffi::Atom, event_mask: Option<c_long>, data: &[T], ) -> Flusher46     pub fn send_client_msg_multi<T: Formattable>(
47         &self,
48         window: c_ulong,        // The window this is "about"; not necessarily this window
49         target_window: c_ulong, // The window we're sending to
50         message_type: ffi::Atom,
51         event_mask: Option<c_long>,
52         data: &[T],
53     ) -> Flusher {
54         let format = T::FORMAT;
55         let size_of_t = mem::size_of::<T>();
56         debug_assert_eq!(size_of_t, format.get_actual_size());
57         let mut event: ffi::XClientMessageEvent = unsafe { mem::uninitialized() };
58         event.type_ = ffi::ClientMessage;
59         event.display = self.display;
60         event.window = window;
61         event.message_type = message_type;
62         event.format = format as c_int;
63 
64         let t_per_payload = format.get_payload_size() / size_of_t;
65         assert!(t_per_payload > 0);
66         let payload_count = data.len() / t_per_payload;
67         let payload_remainder = data.len() % t_per_payload;
68         let payload_ptr = data.as_ptr() as *const ClientMsgPayload;
69 
70         let mut payload_index = 0;
71         while payload_index < payload_count {
72             let payload = unsafe { payload_ptr.offset(payload_index as isize) };
73             payload_index += 1;
74             event.data = unsafe { mem::transmute(*payload) };
75             self.send_event(target_window, event_mask, &event).queue();
76         }
77 
78         if payload_remainder > 0 {
79             let mut payload: ClientMsgPayload = [0; 5];
80             let t_payload = payload.as_mut_ptr() as *mut T;
81             let invalid_payload = unsafe { payload_ptr.offset(payload_index as isize) };
82             let invalid_t_payload = invalid_payload as *const T;
83             let mut t_index = 0;
84             while t_index < payload_remainder {
85                 let valid_t = unsafe { invalid_t_payload.offset(t_index as isize) };
86                 unsafe { (*t_payload.offset(t_index as isize)) = (*valid_t).clone() };
87                 t_index += 1;
88             }
89             event.data = unsafe { mem::transmute(payload) };
90             self.send_event(target_window, event_mask, &event).queue();
91         }
92 
93         Flusher::new(self)
94     }
95 }
96