1#![allow(non_upper_case_globals)]
2use crate::event_source::CGEventSource;
3use crate::geometry::CGPoint;
4
5use bitflags::bitflags;
6use core::ffi::{c_ulong, c_void};
7use core_foundation::{
8 base::{CFRelease, CFRetain, CFTypeID, TCFType},
9 mach_port::{CFMachPort, CFMachPortInvalidate, CFMachPortRef},
10 runloop::{kCFRunLoopCommonModes, CFRunLoop},
11};
12use foreign_types::{foreign_type, ForeignType};
13use std::{mem::ManuallyDrop, ptr};
14
15pub type CGEventField = u32;
16pub type CGKeyCode = u16;
17pub type CGScrollEventUnit = u32;
18
19bitflags! {
20 #[repr(C)]
24 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
25 pub struct CGEventFlags: u64 {
26 const CGEventFlagNull = 0;
27
28 const CGEventFlagAlphaShift = 0x00010000;
30 const CGEventFlagShift = 0x00020000;
31 const CGEventFlagControl = 0x00040000;
32 const CGEventFlagAlternate = 0x00080000;
33 const CGEventFlagCommand = 0x00100000;
34
35 const CGEventFlagHelp = 0x00400000;
37 const CGEventFlagSecondaryFn = 0x00800000;
38
39 const CGEventFlagNumericPad = 0x00200000;
41
42 const CGEventFlagNonCoalesced = 0x00000100;
44 }
45}
46
47#[repr(C)]
66pub struct KeyCode;
67impl KeyCode {
68 pub const ANSI_A: CGKeyCode = 0x00;
69 pub const ANSI_S: CGKeyCode = 0x01;
70 pub const ANSI_D: CGKeyCode = 0x02;
71 pub const ANSI_F: CGKeyCode = 0x03;
72 pub const ANSI_H: CGKeyCode = 0x04;
73 pub const ANSI_G: CGKeyCode = 0x05;
74 pub const ANSI_Z: CGKeyCode = 0x06;
75 pub const ANSI_X: CGKeyCode = 0x07;
76 pub const ANSI_C: CGKeyCode = 0x08;
77 pub const ANSI_V: CGKeyCode = 0x09;
78 pub const ANSI_B: CGKeyCode = 0x0B;
79 pub const ANSI_Q: CGKeyCode = 0x0C;
80 pub const ANSI_W: CGKeyCode = 0x0D;
81 pub const ANSI_E: CGKeyCode = 0x0E;
82 pub const ANSI_R: CGKeyCode = 0x0F;
83 pub const ANSI_Y: CGKeyCode = 0x10;
84 pub const ANSI_T: CGKeyCode = 0x11;
85 pub const ANSI_1: CGKeyCode = 0x12;
86 pub const ANSI_2: CGKeyCode = 0x13;
87 pub const ANSI_3: CGKeyCode = 0x14;
88 pub const ANSI_4: CGKeyCode = 0x15;
89 pub const ANSI_6: CGKeyCode = 0x16;
90 pub const ANSI_5: CGKeyCode = 0x17;
91 pub const ANSI_EQUAL: CGKeyCode = 0x18;
92 pub const ANSI_9: CGKeyCode = 0x19;
93 pub const ANSI_7: CGKeyCode = 0x1A;
94 pub const ANSI_MINUS: CGKeyCode = 0x1B;
95 pub const ANSI_8: CGKeyCode = 0x1C;
96 pub const ANSI_0: CGKeyCode = 0x1D;
97 pub const ANSI_RIGHT_BRACKET: CGKeyCode = 0x1E;
98 pub const ANSI_O: CGKeyCode = 0x1F;
99 pub const ANSI_U: CGKeyCode = 0x20;
100 pub const ANSI_LEFT_BRACKET: CGKeyCode = 0x21;
101 pub const ANSI_I: CGKeyCode = 0x22;
102 pub const ANSI_P: CGKeyCode = 0x23;
103 pub const ANSI_L: CGKeyCode = 0x25;
104 pub const ANSI_J: CGKeyCode = 0x26;
105 pub const ANSI_QUOTE: CGKeyCode = 0x27;
106 pub const ANSI_K: CGKeyCode = 0x28;
107 pub const ANSI_SEMICOLON: CGKeyCode = 0x29;
108 pub const ANSI_BACKSLASH: CGKeyCode = 0x2A;
109 pub const ANSI_COMMA: CGKeyCode = 0x2B;
110 pub const ANSI_SLASH: CGKeyCode = 0x2C;
111 pub const ANSI_N: CGKeyCode = 0x2D;
112 pub const ANSI_M: CGKeyCode = 0x2E;
113 pub const ANSI_PERIOD: CGKeyCode = 0x2F;
114 pub const ANSI_GRAVE: CGKeyCode = 0x32;
115 pub const ANSI_KEYPAD_DECIMAL: CGKeyCode = 0x41;
116 pub const ANSI_KEYPAD_MULTIPLY: CGKeyCode = 0x43;
117 pub const ANSI_KEYPAD_PLUS: CGKeyCode = 0x45;
118 pub const ANSI_KEYPAD_CLEAR: CGKeyCode = 0x47;
119 pub const ANSI_KEYPAD_DIVIDE: CGKeyCode = 0x4B;
120 pub const ANSI_KEYPAD_ENTER: CGKeyCode = 0x4C;
121 pub const ANSI_KEYPAD_MINUS: CGKeyCode = 0x4E;
122 pub const ANSI_KEYPAD_EQUAL: CGKeyCode = 0x51;
123 pub const ANSI_KEYPAD_0: CGKeyCode = 0x52;
124 pub const ANSI_KEYPAD_1: CGKeyCode = 0x53;
125 pub const ANSI_KEYPAD_2: CGKeyCode = 0x54;
126 pub const ANSI_KEYPAD_3: CGKeyCode = 0x55;
127 pub const ANSI_KEYPAD_4: CGKeyCode = 0x56;
128 pub const ANSI_KEYPAD_5: CGKeyCode = 0x57;
129 pub const ANSI_KEYPAD_6: CGKeyCode = 0x58;
130 pub const ANSI_KEYPAD_7: CGKeyCode = 0x59;
131 pub const ANSI_KEYPAD_8: CGKeyCode = 0x5B;
132 pub const ANSI_KEYPAD_9: CGKeyCode = 0x5C;
133 pub const RETURN: CGKeyCode = 0x24;
134 pub const TAB: CGKeyCode = 0x30;
135 pub const SPACE: CGKeyCode = 0x31;
136 pub const DELETE: CGKeyCode = 0x33;
137 pub const ESCAPE: CGKeyCode = 0x35;
138 pub const COMMAND: CGKeyCode = 0x37;
139 pub const SHIFT: CGKeyCode = 0x38;
140 pub const CAPS_LOCK: CGKeyCode = 0x39;
141 pub const OPTION: CGKeyCode = 0x3A;
142 pub const CONTROL: CGKeyCode = 0x3B;
143 pub const RIGHT_COMMAND: CGKeyCode = 0x36;
144 pub const RIGHT_SHIFT: CGKeyCode = 0x3C;
145 pub const RIGHT_OPTION: CGKeyCode = 0x3D;
146 pub const RIGHT_CONTROL: CGKeyCode = 0x3E;
147 pub const FUNCTION: CGKeyCode = 0x3F;
148 pub const F17: CGKeyCode = 0x40;
149 pub const VOLUME_UP: CGKeyCode = 0x48;
150 pub const VOLUME_DOWN: CGKeyCode = 0x49;
151 pub const MUTE: CGKeyCode = 0x4A;
152 pub const F18: CGKeyCode = 0x4F;
153 pub const F19: CGKeyCode = 0x50;
154 pub const F20: CGKeyCode = 0x5A;
155 pub const F5: CGKeyCode = 0x60;
156 pub const F6: CGKeyCode = 0x61;
157 pub const F7: CGKeyCode = 0x62;
158 pub const F3: CGKeyCode = 0x63;
159 pub const F8: CGKeyCode = 0x64;
160 pub const F9: CGKeyCode = 0x65;
161 pub const F11: CGKeyCode = 0x67;
162 pub const F13: CGKeyCode = 0x69;
163 pub const F16: CGKeyCode = 0x6A;
164 pub const F14: CGKeyCode = 0x6B;
165 pub const F10: CGKeyCode = 0x6D;
166 pub const F12: CGKeyCode = 0x6F;
167 pub const F15: CGKeyCode = 0x71;
168 pub const HELP: CGKeyCode = 0x72;
169 pub const HOME: CGKeyCode = 0x73;
170 pub const PAGE_UP: CGKeyCode = 0x74;
171 pub const FORWARD_DELETE: CGKeyCode = 0x75;
172 pub const F4: CGKeyCode = 0x76;
173 pub const END: CGKeyCode = 0x77;
174 pub const F2: CGKeyCode = 0x78;
175 pub const PAGE_DOWN: CGKeyCode = 0x79;
176 pub const F1: CGKeyCode = 0x7A;
177 pub const LEFT_ARROW: CGKeyCode = 0x7B;
178 pub const RIGHT_ARROW: CGKeyCode = 0x7C;
179 pub const DOWN_ARROW: CGKeyCode = 0x7D;
180 pub const UP_ARROW: CGKeyCode = 0x7E;
181 pub const ISO_SECTION: CGKeyCode = 0x0A;
182 pub const JIS_YEN: CGKeyCode = 0x5D;
183 pub const JIS_UNDERSCORE: CGKeyCode = 0x5E;
184 pub const JIS_KEYPAD_COMMA: CGKeyCode = 0x5F;
185 pub const JIS_EISU: CGKeyCode = 0x66;
186 pub const JIS_KANA: CGKeyCode = 0x68;
187}
188
189#[repr(C)]
190pub struct ScrollEventUnit {}
191impl ScrollEventUnit {
192 pub const PIXEL: CGScrollEventUnit = 0;
193 pub const LINE: CGScrollEventUnit = 1;
194}
195
196#[repr(u32)]
200#[derive(Clone, Copy, Debug)]
201pub enum CGEventType {
202 Null = 0,
203
204 LeftMouseDown = 1,
206 LeftMouseUp = 2,
207 RightMouseDown = 3,
208 RightMouseUp = 4,
209 MouseMoved = 5,
210 LeftMouseDragged = 6,
211 RightMouseDragged = 7,
212
213 KeyDown = 10,
215 KeyUp = 11,
216 FlagsChanged = 12,
217
218 ScrollWheel = 22,
220 TabletPointer = 23,
221 TabletProximity = 24,
222 OtherMouseDown = 25,
223 OtherMouseUp = 26,
224 OtherMouseDragged = 27,
225
226 TapDisabledByTimeout = 0xFFFFFFFE,
229 TapDisabledByUserInput = 0xFFFFFFFF,
230}
231
232pub struct EventField;
236impl EventField {
237 pub const MOUSE_EVENT_NUMBER: CGEventField = 0;
241
242 pub const MOUSE_EVENT_CLICK_STATE: CGEventField = 1;
247
248 pub const MOUSE_EVENT_PRESSURE: CGEventField = 2;
253
254 pub const MOUSE_EVENT_BUTTON_NUMBER: CGEventField = 3;
256
257 pub const MOUSE_EVENT_DELTA_X: CGEventField = 4;
260
261 pub const MOUSE_EVENT_DELTA_Y: CGEventField = 5;
264
265 pub const MOUSE_EVENT_INSTANT_MOUSER: CGEventField = 6;
268
269 pub const MOUSE_EVENT_SUB_TYPE: CGEventField = 7;
272
273 pub const KEYBOARD_EVENT_AUTOREPEAT: CGEventField = 8;
276
277 pub const KEYBOARD_EVENT_KEYCODE: CGEventField = 9;
280
281 pub const KEYBOARD_EVENT_KEYBOARD_TYPE: CGEventField = 10;
284
285 pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_1: CGEventField = 11;
290
291 pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_2: CGEventField = 12;
295
296 pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_1: CGEventField = 93;
304
305 pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_2: CGEventField = 94;
312
313 pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_1: CGEventField = 96;
318
319 pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_2: CGEventField = 97;
323
324 pub const SCROLL_WHEEL_EVENT_INSTANT_MOUSER: CGEventField = 14;
328
329 pub const TABLET_EVENT_POINT_X: CGEventField = 15;
332
333 pub const TABLET_EVENT_POINT_Y: CGEventField = 16;
336
337 pub const TABLET_EVENT_POINT_Z: CGEventField = 17;
340
341 pub const TABLET_EVENT_POINT_BUTTONS: CGEventField = 18;
345
346 pub const TABLET_EVENT_POINT_PRESSURE: CGEventField = 19;
350
351 pub const TABLET_EVENT_TILT_X: CGEventField = 20;
354
355 pub const TABLET_EVENT_TILT_Y: CGEventField = 21;
358
359 pub const TABLET_EVENT_ROTATION: CGEventField = 22;
361
362 pub const TABLET_EVENT_TANGENTIAL_PRESSURE: CGEventField = 23;
366
367 pub const TABLET_EVENT_DEVICE_ID: CGEventField = 24;
370
371 pub const TABLET_EVENT_VENDOR_1: CGEventField = 25;
373
374 pub const TABLET_EVENT_VENDOR_2: CGEventField = 26;
376
377 pub const TABLET_EVENT_VENDOR_3: CGEventField = 27;
379
380 pub const TABLET_PROXIMITY_EVENT_VENDOR_ID: CGEventField = 28;
383
384 pub const TABLET_PROXIMITY_EVENT_TABLET_ID: CGEventField = 29;
387
388 pub const TABLET_PROXIMITY_EVENT_POINTER_ID: CGEventField = 30;
391
392 pub const TABLET_PROXIMITY_EVENT_DEVICE_ID: CGEventField = 31;
395
396 pub const TABLET_PROXIMITY_EVENT_SYSTEM_TABLET_ID: CGEventField = 32;
399
400 pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_TYPE: CGEventField = 33;
403
404 pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_SERIAL_NUMBER: CGEventField = 34;
407
408 pub const TABLET_PROXIMITY_EVENT_VENDOR_UNIQUE_ID: CGEventField = 35;
411
412 pub const TABLET_PROXIMITY_EVENT_CAPABILITY_MASK: CGEventField = 36;
415
416 pub const TABLET_PROXIMITY_EVENT_POINTER_TYPE: CGEventField = 37;
418
419 pub const TABLET_PROXIMITY_EVENT_ENTER_PROXIMITY: CGEventField = 38;
423
424 pub const EVENT_TARGET_PROCESS_SERIAL_NUMBER: CGEventField = 39;
427
428 pub const EVENT_TARGET_UNIX_PROCESS_ID: CGEventField = 40;
430
431 pub const EVENT_SOURCE_UNIX_PROCESS_ID: CGEventField = 41;
433
434 pub const EVENT_SOURCE_USER_DATA: CGEventField = 42;
437
438 pub const EVENT_SOURCE_USER_ID: CGEventField = 43;
440
441 pub const EVENT_SOURCE_GROUP_ID: CGEventField = 44;
444
445 pub const EVENT_SOURCE_STATE_ID: CGEventField = 45;
448
449 pub const SCROLL_WHEEL_EVENT_IS_CONTINUOUS: CGEventField = 88;
454
455 pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER: CGEventField = 91;
457 pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER_THAT_CAN_HANDLE_THIS_EVENT: CGEventField = 92;
458}
459
460#[repr(C)]
462#[derive(Clone, Copy, Debug)]
463pub enum CGMouseButton {
464 Left,
465 Right,
466 Center,
467}
468
469#[repr(C)]
471#[derive(Clone, Copy, Debug)]
472pub enum CGEventTapLocation {
473 HID,
474 Session,
475 AnnotatedSession,
476}
477
478#[repr(u32)]
483#[derive(Clone, Copy, Debug)]
484pub enum CGEventTapPlacement {
485 HeadInsertEventTap = 0,
486 TailAppendEventTap,
487}
488
489#[repr(u32)]
492#[derive(Clone, Copy, Debug)]
493pub enum CGEventTapOptions {
494 Default = 0x00000000,
495 ListenOnly = 0x00000001,
496}
497
498pub type CGEventMask = u64;
499macro_rules! CGEventMaskBit {
501 ($eventType:expr) => {
502 (1 << $eventType as CGEventMask)
503 };
504}
505
506pub type CGEventTapProxy = *const c_void;
507
508pub enum CallbackResult {
512 Keep,
514 Drop,
516 Replace(CGEvent),
518}
519
520type CGEventTapCallbackFn<'tap_life> =
521 Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life>;
522type CGEventTapCallBackInternal = unsafe extern "C" fn(
523 proxy: CGEventTapProxy,
524 etype: CGEventType,
525 event: crate::sys::CGEventRef,
526 user_info: *const c_void,
527) -> crate::sys::CGEventRef;
528
529unsafe extern "C" fn cg_event_tap_callback_internal(
530 proxy: CGEventTapProxy,
531 etype: CGEventType,
532 event: crate::sys::CGEventRef,
533 user_info: *const c_void,
534) -> crate::sys::CGEventRef {
535 let callback = user_info as *mut CGEventTapCallbackFn;
536 let event = ManuallyDrop::new(CGEvent::from_ptr(event));
537 let response = (*callback)(proxy, etype, &event);
538 use CallbackResult::*;
539 match response {
540 Keep => event.as_ptr(),
541 Drop => ptr::null_mut(),
542 Replace(new_event) => ManuallyDrop::new(new_event).as_ptr(),
543 }
544}
545
546#[must_use = "CGEventTap is disabled when dropped"]
564pub struct CGEventTap<'tap_life> {
565 mach_port: CFMachPort,
566 _callback: Box<CGEventTapCallbackFn<'tap_life>>,
567}
568
569impl CGEventTap<'static> {
570 pub fn new<F: Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + Send + 'static>(
571 tap: CGEventTapLocation,
572 place: CGEventTapPlacement,
573 options: CGEventTapOptions,
574 events_of_interest: std::vec::Vec<CGEventType>,
575 callback: F,
576 ) -> Result<Self, ()> {
577 unsafe { Self::new_unchecked(tap, place, options, events_of_interest, callback) }
580 }
581}
582
583impl<'tap_life> CGEventTap<'tap_life> {
584 pub fn with_enabled<R>(
590 tap: CGEventTapLocation,
591 place: CGEventTapPlacement,
592 options: CGEventTapOptions,
593 events_of_interest: std::vec::Vec<CGEventType>,
594 callback: impl Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life,
595 with_fn: impl FnOnce() -> R,
596 ) -> Result<R, ()> {
597 let event_tap: Self =
603 unsafe { Self::new_unchecked(tap, place, options, events_of_interest, callback)? };
604 let loop_source = event_tap
605 .mach_port()
606 .create_runloop_source(0)
607 .expect("Runloop source creation failed");
608 CFRunLoop::get_current().add_source(&loop_source, unsafe { kCFRunLoopCommonModes });
609 event_tap.enable();
610 Ok(with_fn())
611 }
612
613 pub unsafe fn new_unchecked(
618 tap: CGEventTapLocation,
619 place: CGEventTapPlacement,
620 options: CGEventTapOptions,
621 events_of_interest: std::vec::Vec<CGEventType>,
622 callback: impl Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life,
623 ) -> Result<Self, ()> {
624 let event_mask: CGEventMask = events_of_interest
625 .iter()
626 .fold(CGEventType::Null as CGEventMask, |mask, &etype| {
627 mask | CGEventMaskBit!(etype)
628 });
629 let cb: Box<CGEventTapCallbackFn> = Box::new(Box::new(callback));
630 let cbr = Box::into_raw(cb);
631 unsafe {
632 let event_tap_ref = CGEventTapCreate(
633 tap,
634 place,
635 options,
636 event_mask,
637 cg_event_tap_callback_internal,
638 cbr as *const c_void,
639 );
640
641 if !event_tap_ref.is_null() {
642 Ok(Self {
643 mach_port: (CFMachPort::wrap_under_create_rule(event_tap_ref)),
644 _callback: Box::from_raw(cbr),
645 })
646 } else {
647 let _ = Box::from_raw(cbr);
648 Err(())
649 }
650 }
651 }
652
653 pub fn mach_port(&self) -> &CFMachPort {
654 &self.mach_port
655 }
656
657 pub fn enable(&self) {
658 unsafe { CGEventTapEnable(self.mach_port.as_concrete_TypeRef(), true) }
659 }
660}
661
662impl Drop for CGEventTap<'_> {
663 fn drop(&mut self) {
664 unsafe { CFMachPortInvalidate(self.mach_port.as_CFTypeRef() as *mut _) };
665 }
666}
667
668foreign_type! {
669 #[doc(hidden)]
670 pub unsafe type CGEvent {
671 type CType = crate::sys::CGEvent;
672 fn drop = |p| CFRelease(p as *mut _);
673 fn clone = |p| CFRetain(p as *const _) as *mut _;
674 }
675}
676
677impl CGEvent {
678 pub fn type_id() -> CFTypeID {
679 unsafe { CGEventGetTypeID() }
680 }
681
682 pub fn new(source: CGEventSource) -> Result<CGEvent, ()> {
683 unsafe {
684 let event_ref = CGEventCreate(source.as_ptr());
685 if !event_ref.is_null() {
686 Ok(Self::from_ptr(event_ref))
687 } else {
688 Err(())
689 }
690 }
691 }
692
693 pub fn new_keyboard_event(
694 source: CGEventSource,
695 keycode: CGKeyCode,
696 keydown: bool,
697 ) -> Result<CGEvent, ()> {
698 unsafe {
699 let event_ref = CGEventCreateKeyboardEvent(source.as_ptr(), keycode, keydown);
700 if !event_ref.is_null() {
701 Ok(Self::from_ptr(event_ref))
702 } else {
703 Err(())
704 }
705 }
706 }
707
708 pub fn new_mouse_event(
709 source: CGEventSource,
710 mouse_type: CGEventType,
711 mouse_cursor_position: CGPoint,
712 mouse_button: CGMouseButton,
713 ) -> Result<CGEvent, ()> {
714 unsafe {
715 let event_ref = CGEventCreateMouseEvent(
716 source.as_ptr(),
717 mouse_type,
718 mouse_cursor_position,
719 mouse_button,
720 );
721 if !event_ref.is_null() {
722 Ok(Self::from_ptr(event_ref))
723 } else {
724 Err(())
725 }
726 }
727 }
728
729 #[cfg(feature = "highsierra")]
730 pub fn new_scroll_event(
731 source: CGEventSource,
732 units: CGScrollEventUnit,
733 wheel_count: u32,
734 wheel1: i32,
735 wheel2: i32,
736 wheel3: i32,
737 ) -> Result<CGEvent, ()> {
738 unsafe {
739 let event_ref = CGEventCreateScrollWheelEvent2(
740 source.as_ptr(),
741 units,
742 wheel_count,
743 wheel1,
744 wheel2,
745 wheel3,
746 );
747 if !event_ref.is_null() {
748 Ok(Self::from_ptr(event_ref))
749 } else {
750 Err(())
751 }
752 }
753 }
754
755 pub fn post(&self, tap_location: CGEventTapLocation) {
756 unsafe {
757 CGEventPost(tap_location, self.as_ptr());
758 }
759 }
760
761 pub fn post_from_tap(&self, tap_proxy: CGEventTapProxy) {
762 unsafe {
763 CGEventTapPostEvent(tap_proxy, self.as_ptr());
764 }
765 }
766
767 pub fn location(&self) -> CGPoint {
768 unsafe { CGEventGetLocation(self.as_ptr()) }
769 }
770
771 pub fn set_location(&self, location: CGPoint) {
772 unsafe {
773 CGEventSetLocation(self.as_ptr(), location);
774 }
775 }
776
777 #[cfg(feature = "elcapitan")]
778 pub fn post_to_pid(&self, pid: libc::pid_t) {
779 unsafe {
780 CGEventPostToPid(pid, self.as_ptr());
781 }
782 }
783
784 pub fn set_flags(&self, flags: CGEventFlags) {
785 unsafe {
786 CGEventSetFlags(self.as_ptr(), flags);
787 }
788 }
789
790 pub fn get_flags(&self) -> CGEventFlags {
791 unsafe { CGEventGetFlags(self.as_ptr()) }
792 }
793
794 pub fn set_type(&self, event_type: CGEventType) {
795 unsafe {
796 CGEventSetType(self.as_ptr(), event_type);
797 }
798 }
799
800 pub fn get_type(&self) -> CGEventType {
801 unsafe { CGEventGetType(self.as_ptr()) }
802 }
803
804 pub fn set_string_from_utf16_unchecked(&self, buf: &[u16]) {
805 let buflen = buf.len() as c_ulong;
806 unsafe {
807 CGEventKeyboardSetUnicodeString(self.as_ptr(), buflen, buf.as_ptr());
808 }
809 }
810
811 pub fn set_string(&self, string: &str) {
812 let buf: Vec<u16> = string.encode_utf16().collect();
813 self.set_string_from_utf16_unchecked(&buf);
814 }
815
816 pub fn get_integer_value_field(&self, field: CGEventField) -> i64 {
817 unsafe { CGEventGetIntegerValueField(self.as_ptr(), field) }
818 }
819
820 pub fn set_integer_value_field(&self, field: CGEventField, value: i64) {
821 unsafe { CGEventSetIntegerValueField(self.as_ptr(), field, value) }
822 }
823
824 pub fn get_double_value_field(&self, field: CGEventField) -> f64 {
825 unsafe { CGEventGetDoubleValueField(self.as_ptr(), field) }
826 }
827
828 pub fn set_double_value_field(&self, field: CGEventField, value: f64) {
829 unsafe { CGEventSetDoubleValueField(self.as_ptr(), field, value) }
830 }
831}
832
833#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
834extern "C" {
835 fn CGEventGetTypeID() -> CFTypeID;
839
840 fn CGEventCreate(source: crate::sys::CGEventSourceRef) -> crate::sys::CGEventRef;
843
844 fn CGEventCreateKeyboardEvent(
855 source: crate::sys::CGEventSourceRef,
856 keycode: CGKeyCode,
857 keydown: bool,
858 ) -> crate::sys::CGEventRef;
859
860 fn CGEventCreateMouseEvent(
874 source: crate::sys::CGEventSourceRef,
875 mouseType: CGEventType,
876 mouseCursorPosition: CGPoint,
877 mouseButton: CGMouseButton,
878 ) -> crate::sys::CGEventRef;
879
880 #[cfg(feature = "highsierra")]
887 fn CGEventCreateScrollWheelEvent2(
888 source: crate::sys::CGEventSourceRef,
889 units: CGScrollEventUnit,
890 wheelCount: u32,
891 wheel1: i32,
892 wheel2: i32,
893 wheel3: i32,
894 ) -> crate::sys::CGEventRef;
895
896 fn CGEventPost(tapLocation: CGEventTapLocation, event: crate::sys::CGEventRef);
902
903 fn CGEventTapPostEvent(tapProxy: CGEventTapProxy, event: crate::sys::CGEventRef);
904
905 #[cfg(feature = "elcapitan")]
906 fn CGEventPostToPid(pid: libc::pid_t, event: crate::sys::CGEventRef);
908
909 fn CGEventSetFlags(event: crate::sys::CGEventRef, flags: CGEventFlags);
911
912 fn CGEventGetFlags(event: crate::sys::CGEventRef) -> CGEventFlags;
914
915 fn CGEventGetLocation(event: crate::sys::CGEventRef) -> CGPoint;
920
921 fn CGEventSetType(event: crate::sys::CGEventRef, eventType: CGEventType);
923
924 fn CGEventGetType(event: crate::sys::CGEventRef) -> CGEventType;
926
927 fn CGEventKeyboardSetUnicodeString(
936 event: crate::sys::CGEventRef,
937 length: c_ulong,
938 string: *const u16,
939 );
940
941 fn CGEventGetIntegerValueField(event: crate::sys::CGEventRef, field: CGEventField) -> i64;
943
944 fn CGEventSetIntegerValueField(event: crate::sys::CGEventRef, field: CGEventField, value: i64);
955
956 fn CGEventGetDoubleValueField(event: crate::sys::CGEventRef, field: CGEventField) -> f64;
962
963 fn CGEventSetDoubleValueField(event: crate::sys::CGEventRef, field: CGEventField, value: f64);
973
974 fn CGEventTapCreate(
976 tap: CGEventTapLocation,
977 place: CGEventTapPlacement,
978 options: CGEventTapOptions,
979 eventsOfInterest: CGEventMask,
980 callback: CGEventTapCallBackInternal,
981 userInfo: *const c_void,
982 ) -> CFMachPortRef;
983
984 fn CGEventTapEnable(tap: CFMachPortRef, enable: bool);
991
992 fn CGEventSetLocation(event: crate::sys::CGEventRef, location: CGPoint);
994}