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