#![allow(non_upper_case_globals)]
use crate::event_source::CGEventSource;
use crate::geometry::CGPoint;
use bitflags::bitflags;
use core::ffi::{c_ulong, c_void};
use core_foundation::{
base::{CFRelease, CFRetain, CFTypeID, TCFType},
mach_port::{CFMachPort, CFMachPortInvalidate, CFMachPortRef},
runloop::{kCFRunLoopCommonModes, CFRunLoop},
};
use foreign_types::{foreign_type, ForeignType};
use std::{mem::ManuallyDrop, ptr};
pub type CGEventField = u32;
pub type CGKeyCode = u16;
pub type CGScrollEventUnit = u32;
bitflags! {
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CGEventFlags: u64 {
const CGEventFlagNull = 0;
const CGEventFlagAlphaShift = 0x00010000;
const CGEventFlagShift = 0x00020000;
const CGEventFlagControl = 0x00040000;
const CGEventFlagAlternate = 0x00080000;
const CGEventFlagCommand = 0x00100000;
const CGEventFlagHelp = 0x00400000;
const CGEventFlagSecondaryFn = 0x00800000;
const CGEventFlagNumericPad = 0x00200000;
const CGEventFlagNonCoalesced = 0x00000100;
}
}
#[repr(C)]
pub struct KeyCode;
impl KeyCode {
pub const ANSI_A: CGKeyCode = 0x00;
pub const ANSI_S: CGKeyCode = 0x01;
pub const ANSI_D: CGKeyCode = 0x02;
pub const ANSI_F: CGKeyCode = 0x03;
pub const ANSI_H: CGKeyCode = 0x04;
pub const ANSI_G: CGKeyCode = 0x05;
pub const ANSI_Z: CGKeyCode = 0x06;
pub const ANSI_X: CGKeyCode = 0x07;
pub const ANSI_C: CGKeyCode = 0x08;
pub const ANSI_V: CGKeyCode = 0x09;
pub const ANSI_B: CGKeyCode = 0x0B;
pub const ANSI_Q: CGKeyCode = 0x0C;
pub const ANSI_W: CGKeyCode = 0x0D;
pub const ANSI_E: CGKeyCode = 0x0E;
pub const ANSI_R: CGKeyCode = 0x0F;
pub const ANSI_Y: CGKeyCode = 0x10;
pub const ANSI_T: CGKeyCode = 0x11;
pub const ANSI_1: CGKeyCode = 0x12;
pub const ANSI_2: CGKeyCode = 0x13;
pub const ANSI_3: CGKeyCode = 0x14;
pub const ANSI_4: CGKeyCode = 0x15;
pub const ANSI_6: CGKeyCode = 0x16;
pub const ANSI_5: CGKeyCode = 0x17;
pub const ANSI_EQUAL: CGKeyCode = 0x18;
pub const ANSI_9: CGKeyCode = 0x19;
pub const ANSI_7: CGKeyCode = 0x1A;
pub const ANSI_MINUS: CGKeyCode = 0x1B;
pub const ANSI_8: CGKeyCode = 0x1C;
pub const ANSI_0: CGKeyCode = 0x1D;
pub const ANSI_RIGHT_BRACKET: CGKeyCode = 0x1E;
pub const ANSI_O: CGKeyCode = 0x1F;
pub const ANSI_U: CGKeyCode = 0x20;
pub const ANSI_LEFT_BRACKET: CGKeyCode = 0x21;
pub const ANSI_I: CGKeyCode = 0x22;
pub const ANSI_P: CGKeyCode = 0x23;
pub const ANSI_L: CGKeyCode = 0x25;
pub const ANSI_J: CGKeyCode = 0x26;
pub const ANSI_QUOTE: CGKeyCode = 0x27;
pub const ANSI_K: CGKeyCode = 0x28;
pub const ANSI_SEMICOLON: CGKeyCode = 0x29;
pub const ANSI_BACKSLASH: CGKeyCode = 0x2A;
pub const ANSI_COMMA: CGKeyCode = 0x2B;
pub const ANSI_SLASH: CGKeyCode = 0x2C;
pub const ANSI_N: CGKeyCode = 0x2D;
pub const ANSI_M: CGKeyCode = 0x2E;
pub const ANSI_PERIOD: CGKeyCode = 0x2F;
pub const ANSI_GRAVE: CGKeyCode = 0x32;
pub const ANSI_KEYPAD_DECIMAL: CGKeyCode = 0x41;
pub const ANSI_KEYPAD_MULTIPLY: CGKeyCode = 0x43;
pub const ANSI_KEYPAD_PLUS: CGKeyCode = 0x45;
pub const ANSI_KEYPAD_CLEAR: CGKeyCode = 0x47;
pub const ANSI_KEYPAD_DIVIDE: CGKeyCode = 0x4B;
pub const ANSI_KEYPAD_ENTER: CGKeyCode = 0x4C;
pub const ANSI_KEYPAD_MINUS: CGKeyCode = 0x4E;
pub const ANSI_KEYPAD_EQUAL: CGKeyCode = 0x51;
pub const ANSI_KEYPAD_0: CGKeyCode = 0x52;
pub const ANSI_KEYPAD_1: CGKeyCode = 0x53;
pub const ANSI_KEYPAD_2: CGKeyCode = 0x54;
pub const ANSI_KEYPAD_3: CGKeyCode = 0x55;
pub const ANSI_KEYPAD_4: CGKeyCode = 0x56;
pub const ANSI_KEYPAD_5: CGKeyCode = 0x57;
pub const ANSI_KEYPAD_6: CGKeyCode = 0x58;
pub const ANSI_KEYPAD_7: CGKeyCode = 0x59;
pub const ANSI_KEYPAD_8: CGKeyCode = 0x5B;
pub const ANSI_KEYPAD_9: CGKeyCode = 0x5C;
pub const RETURN: CGKeyCode = 0x24;
pub const TAB: CGKeyCode = 0x30;
pub const SPACE: CGKeyCode = 0x31;
pub const DELETE: CGKeyCode = 0x33;
pub const ESCAPE: CGKeyCode = 0x35;
pub const COMMAND: CGKeyCode = 0x37;
pub const SHIFT: CGKeyCode = 0x38;
pub const CAPS_LOCK: CGKeyCode = 0x39;
pub const OPTION: CGKeyCode = 0x3A;
pub const CONTROL: CGKeyCode = 0x3B;
pub const RIGHT_COMMAND: CGKeyCode = 0x36;
pub const RIGHT_SHIFT: CGKeyCode = 0x3C;
pub const RIGHT_OPTION: CGKeyCode = 0x3D;
pub const RIGHT_CONTROL: CGKeyCode = 0x3E;
pub const FUNCTION: CGKeyCode = 0x3F;
pub const F17: CGKeyCode = 0x40;
pub const VOLUME_UP: CGKeyCode = 0x48;
pub const VOLUME_DOWN: CGKeyCode = 0x49;
pub const MUTE: CGKeyCode = 0x4A;
pub const F18: CGKeyCode = 0x4F;
pub const F19: CGKeyCode = 0x50;
pub const F20: CGKeyCode = 0x5A;
pub const F5: CGKeyCode = 0x60;
pub const F6: CGKeyCode = 0x61;
pub const F7: CGKeyCode = 0x62;
pub const F3: CGKeyCode = 0x63;
pub const F8: CGKeyCode = 0x64;
pub const F9: CGKeyCode = 0x65;
pub const F11: CGKeyCode = 0x67;
pub const F13: CGKeyCode = 0x69;
pub const F16: CGKeyCode = 0x6A;
pub const F14: CGKeyCode = 0x6B;
pub const F10: CGKeyCode = 0x6D;
pub const F12: CGKeyCode = 0x6F;
pub const F15: CGKeyCode = 0x71;
pub const HELP: CGKeyCode = 0x72;
pub const HOME: CGKeyCode = 0x73;
pub const PAGE_UP: CGKeyCode = 0x74;
pub const FORWARD_DELETE: CGKeyCode = 0x75;
pub const F4: CGKeyCode = 0x76;
pub const END: CGKeyCode = 0x77;
pub const F2: CGKeyCode = 0x78;
pub const PAGE_DOWN: CGKeyCode = 0x79;
pub const F1: CGKeyCode = 0x7A;
pub const LEFT_ARROW: CGKeyCode = 0x7B;
pub const RIGHT_ARROW: CGKeyCode = 0x7C;
pub const DOWN_ARROW: CGKeyCode = 0x7D;
pub const UP_ARROW: CGKeyCode = 0x7E;
pub const ISO_SECTION: CGKeyCode = 0x0A;
pub const JIS_YEN: CGKeyCode = 0x5D;
pub const JIS_UNDERSCORE: CGKeyCode = 0x5E;
pub const JIS_KEYPAD_COMMA: CGKeyCode = 0x5F;
pub const JIS_EISU: CGKeyCode = 0x66;
pub const JIS_KANA: CGKeyCode = 0x68;
}
#[repr(C)]
pub struct ScrollEventUnit {}
impl ScrollEventUnit {
pub const PIXEL: CGScrollEventUnit = 0;
pub const LINE: CGScrollEventUnit = 1;
}
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventType {
Null = 0,
LeftMouseDown = 1,
LeftMouseUp = 2,
RightMouseDown = 3,
RightMouseUp = 4,
MouseMoved = 5,
LeftMouseDragged = 6,
RightMouseDragged = 7,
KeyDown = 10,
KeyUp = 11,
FlagsChanged = 12,
ScrollWheel = 22,
TabletPointer = 23,
TabletProximity = 24,
OtherMouseDown = 25,
OtherMouseUp = 26,
OtherMouseDragged = 27,
TapDisabledByTimeout = 0xFFFFFFFE,
TapDisabledByUserInput = 0xFFFFFFFF,
}
pub struct EventField;
impl EventField {
pub const MOUSE_EVENT_NUMBER: CGEventField = 0;
pub const MOUSE_EVENT_CLICK_STATE: CGEventField = 1;
pub const MOUSE_EVENT_PRESSURE: CGEventField = 2;
pub const MOUSE_EVENT_BUTTON_NUMBER: CGEventField = 3;
pub const MOUSE_EVENT_DELTA_X: CGEventField = 4;
pub const MOUSE_EVENT_DELTA_Y: CGEventField = 5;
pub const MOUSE_EVENT_INSTANT_MOUSER: CGEventField = 6;
pub const MOUSE_EVENT_SUB_TYPE: CGEventField = 7;
pub const KEYBOARD_EVENT_AUTOREPEAT: CGEventField = 8;
pub const KEYBOARD_EVENT_KEYCODE: CGEventField = 9;
pub const KEYBOARD_EVENT_KEYBOARD_TYPE: CGEventField = 10;
pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_1: CGEventField = 11;
pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_2: CGEventField = 12;
pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_1: CGEventField = 93;
pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_2: CGEventField = 94;
pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_1: CGEventField = 96;
pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_2: CGEventField = 97;
pub const SCROLL_WHEEL_EVENT_INSTANT_MOUSER: CGEventField = 14;
pub const TABLET_EVENT_POINT_X: CGEventField = 15;
pub const TABLET_EVENT_POINT_Y: CGEventField = 16;
pub const TABLET_EVENT_POINT_Z: CGEventField = 17;
pub const TABLET_EVENT_POINT_BUTTONS: CGEventField = 18;
pub const TABLET_EVENT_POINT_PRESSURE: CGEventField = 19;
pub const TABLET_EVENT_TILT_X: CGEventField = 20;
pub const TABLET_EVENT_TILT_Y: CGEventField = 21;
pub const TABLET_EVENT_ROTATION: CGEventField = 22;
pub const TABLET_EVENT_TANGENTIAL_PRESSURE: CGEventField = 23;
pub const TABLET_EVENT_DEVICE_ID: CGEventField = 24;
pub const TABLET_EVENT_VENDOR_1: CGEventField = 25;
pub const TABLET_EVENT_VENDOR_2: CGEventField = 26;
pub const TABLET_EVENT_VENDOR_3: CGEventField = 27;
pub const TABLET_PROXIMITY_EVENT_VENDOR_ID: CGEventField = 28;
pub const TABLET_PROXIMITY_EVENT_TABLET_ID: CGEventField = 29;
pub const TABLET_PROXIMITY_EVENT_POINTER_ID: CGEventField = 30;
pub const TABLET_PROXIMITY_EVENT_DEVICE_ID: CGEventField = 31;
pub const TABLET_PROXIMITY_EVENT_SYSTEM_TABLET_ID: CGEventField = 32;
pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_TYPE: CGEventField = 33;
pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_SERIAL_NUMBER: CGEventField = 34;
pub const TABLET_PROXIMITY_EVENT_VENDOR_UNIQUE_ID: CGEventField = 35;
pub const TABLET_PROXIMITY_EVENT_CAPABILITY_MASK: CGEventField = 36;
pub const TABLET_PROXIMITY_EVENT_POINTER_TYPE: CGEventField = 37;
pub const TABLET_PROXIMITY_EVENT_ENTER_PROXIMITY: CGEventField = 38;
pub const EVENT_TARGET_PROCESS_SERIAL_NUMBER: CGEventField = 39;
pub const EVENT_TARGET_UNIX_PROCESS_ID: CGEventField = 40;
pub const EVENT_SOURCE_UNIX_PROCESS_ID: CGEventField = 41;
pub const EVENT_SOURCE_USER_DATA: CGEventField = 42;
pub const EVENT_SOURCE_USER_ID: CGEventField = 43;
pub const EVENT_SOURCE_GROUP_ID: CGEventField = 44;
pub const EVENT_SOURCE_STATE_ID: CGEventField = 45;
pub const SCROLL_WHEEL_EVENT_IS_CONTINUOUS: CGEventField = 88;
pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER: CGEventField = 91;
pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER_THAT_CAN_HANDLE_THIS_EVENT: CGEventField = 92;
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGMouseButton {
Left,
Right,
Center,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapLocation {
HID,
Session,
AnnotatedSession,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapPlacement {
HeadInsertEventTap = 0,
TailAppendEventTap,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapOptions {
Default = 0x00000000,
ListenOnly = 0x00000001,
}
pub type CGEventMask = u64;
macro_rules! CGEventMaskBit {
($eventType:expr) => {
(1 << $eventType as CGEventMask)
};
}
pub type CGEventTapProxy = *const c_void;
pub enum CallbackResult {
Keep,
Drop,
Replace(CGEvent),
}
type CGEventTapCallbackFn<'tap_life> =
Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life>;
type CGEventTapCallBackInternal = unsafe extern "C" fn(
proxy: CGEventTapProxy,
etype: CGEventType,
event: crate::sys::CGEventRef,
user_info: *const c_void,
) -> crate::sys::CGEventRef;
unsafe extern "C" fn cg_event_tap_callback_internal(
proxy: CGEventTapProxy,
etype: CGEventType,
event: crate::sys::CGEventRef,
user_info: *const c_void,
) -> crate::sys::CGEventRef {
let callback = user_info as *mut CGEventTapCallbackFn;
let event = ManuallyDrop::new(CGEvent::from_ptr(event));
let response = (*callback)(proxy, etype, &event);
use CallbackResult::*;
match response {
Keep => event.as_ptr(),
Drop => ptr::null_mut(),
Replace(new_event) => ManuallyDrop::new(new_event).as_ptr(),
}
}
#[must_use = "CGEventTap is disabled when dropped"]
pub struct CGEventTap<'tap_life> {
mach_port: CFMachPort,
_callback: Box<CGEventTapCallbackFn<'tap_life>>,
}
impl CGEventTap<'static> {
pub fn new<F: Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + Send + 'static>(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
events_of_interest: std::vec::Vec<CGEventType>,
callback: F,
) -> Result<Self, ()> {
unsafe { Self::new_unchecked(tap, place, options, events_of_interest, callback) }
}
}
impl<'tap_life> CGEventTap<'tap_life> {
pub fn with_enabled<R>(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
events_of_interest: std::vec::Vec<CGEventType>,
callback: impl Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life,
with_fn: impl FnOnce() -> R,
) -> Result<R, ()> {
let event_tap: Self =
unsafe { Self::new_unchecked(tap, place, options, events_of_interest, callback)? };
let loop_source = event_tap
.mach_port()
.create_runloop_source(0)
.expect("Runloop source creation failed");
CFRunLoop::get_current().add_source(&loop_source, unsafe { kCFRunLoopCommonModes });
event_tap.enable();
Ok(with_fn())
}
pub unsafe fn new_unchecked(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
events_of_interest: std::vec::Vec<CGEventType>,
callback: impl Fn(CGEventTapProxy, CGEventType, &CGEvent) -> CallbackResult + 'tap_life,
) -> Result<Self, ()> {
let event_mask: CGEventMask = events_of_interest
.iter()
.fold(CGEventType::Null as CGEventMask, |mask, &etype| {
mask | CGEventMaskBit!(etype)
});
let cb: Box<CGEventTapCallbackFn> = Box::new(Box::new(callback));
let cbr = Box::into_raw(cb);
unsafe {
let event_tap_ref = CGEventTapCreate(
tap,
place,
options,
event_mask,
cg_event_tap_callback_internal,
cbr as *const c_void,
);
if !event_tap_ref.is_null() {
Ok(Self {
mach_port: (CFMachPort::wrap_under_create_rule(event_tap_ref)),
_callback: Box::from_raw(cbr),
})
} else {
let _ = Box::from_raw(cbr);
Err(())
}
}
}
pub fn mach_port(&self) -> &CFMachPort {
&self.mach_port
}
pub fn enable(&self) {
unsafe { CGEventTapEnable(self.mach_port.as_concrete_TypeRef(), true) }
}
}
impl Drop for CGEventTap<'_> {
fn drop(&mut self) {
unsafe { CFMachPortInvalidate(self.mach_port.as_CFTypeRef() as *mut _) };
}
}
foreign_type! {
#[doc(hidden)]
pub unsafe type CGEvent {
type CType = crate::sys::CGEvent;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGEvent {
pub fn type_id() -> CFTypeID {
unsafe { CGEventGetTypeID() }
}
pub fn new(source: CGEventSource) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreate(source.as_ptr());
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn new_keyboard_event(
source: CGEventSource,
keycode: CGKeyCode,
keydown: bool,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateKeyboardEvent(source.as_ptr(), keycode, keydown);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn new_mouse_event(
source: CGEventSource,
mouse_type: CGEventType,
mouse_cursor_position: CGPoint,
mouse_button: CGMouseButton,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateMouseEvent(
source.as_ptr(),
mouse_type,
mouse_cursor_position,
mouse_button,
);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
#[cfg(feature = "highsierra")]
pub fn new_scroll_event(
source: CGEventSource,
units: CGScrollEventUnit,
wheel_count: u32,
wheel1: i32,
wheel2: i32,
wheel3: i32,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateScrollWheelEvent2(
source.as_ptr(),
units,
wheel_count,
wheel1,
wheel2,
wheel3,
);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn post(&self, tap_location: CGEventTapLocation) {
unsafe {
CGEventPost(tap_location, self.as_ptr());
}
}
pub fn post_from_tap(&self, tap_proxy: CGEventTapProxy) {
unsafe {
CGEventTapPostEvent(tap_proxy, self.as_ptr());
}
}
pub fn location(&self) -> CGPoint {
unsafe { CGEventGetLocation(self.as_ptr()) }
}
pub fn set_location(&self, location: CGPoint) {
unsafe {
CGEventSetLocation(self.as_ptr(), location);
}
}
#[cfg(feature = "elcapitan")]
pub fn post_to_pid(&self, pid: libc::pid_t) {
unsafe {
CGEventPostToPid(pid, self.as_ptr());
}
}
pub fn set_flags(&self, flags: CGEventFlags) {
unsafe {
CGEventSetFlags(self.as_ptr(), flags);
}
}
pub fn get_flags(&self) -> CGEventFlags {
unsafe { CGEventGetFlags(self.as_ptr()) }
}
pub fn set_type(&self, event_type: CGEventType) {
unsafe {
CGEventSetType(self.as_ptr(), event_type);
}
}
pub fn get_type(&self) -> CGEventType {
unsafe { CGEventGetType(self.as_ptr()) }
}
pub fn set_string_from_utf16_unchecked(&self, buf: &[u16]) {
let buflen = buf.len() as c_ulong;
unsafe {
CGEventKeyboardSetUnicodeString(self.as_ptr(), buflen, buf.as_ptr());
}
}
pub fn set_string(&self, string: &str) {
let buf: Vec<u16> = string.encode_utf16().collect();
self.set_string_from_utf16_unchecked(&buf);
}
pub fn get_integer_value_field(&self, field: CGEventField) -> i64 {
unsafe { CGEventGetIntegerValueField(self.as_ptr(), field) }
}
pub fn set_integer_value_field(&self, field: CGEventField, value: i64) {
unsafe { CGEventSetIntegerValueField(self.as_ptr(), field, value) }
}
pub fn get_double_value_field(&self, field: CGEventField) -> f64 {
unsafe { CGEventGetDoubleValueField(self.as_ptr(), field) }
}
pub fn set_double_value_field(&self, field: CGEventField, value: f64) {
unsafe { CGEventSetDoubleValueField(self.as_ptr(), field, value) }
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGEventGetTypeID() -> CFTypeID;
fn CGEventCreate(source: crate::sys::CGEventSourceRef) -> crate::sys::CGEventRef;
fn CGEventCreateKeyboardEvent(
source: crate::sys::CGEventSourceRef,
keycode: CGKeyCode,
keydown: bool,
) -> crate::sys::CGEventRef;
fn CGEventCreateMouseEvent(
source: crate::sys::CGEventSourceRef,
mouseType: CGEventType,
mouseCursorPosition: CGPoint,
mouseButton: CGMouseButton,
) -> crate::sys::CGEventRef;
#[cfg(feature = "highsierra")]
fn CGEventCreateScrollWheelEvent2(
source: crate::sys::CGEventSourceRef,
units: CGScrollEventUnit,
wheelCount: u32,
wheel1: i32,
wheel2: i32,
wheel3: i32,
) -> crate::sys::CGEventRef;
fn CGEventPost(tapLocation: CGEventTapLocation, event: crate::sys::CGEventRef);
fn CGEventTapPostEvent(tapProxy: CGEventTapProxy, event: crate::sys::CGEventRef);
#[cfg(feature = "elcapitan")]
fn CGEventPostToPid(pid: libc::pid_t, event: crate::sys::CGEventRef);
fn CGEventSetFlags(event: crate::sys::CGEventRef, flags: CGEventFlags);
fn CGEventGetFlags(event: crate::sys::CGEventRef) -> CGEventFlags;
fn CGEventGetLocation(event: crate::sys::CGEventRef) -> CGPoint;
fn CGEventSetType(event: crate::sys::CGEventRef, eventType: CGEventType);
fn CGEventGetType(event: crate::sys::CGEventRef) -> CGEventType;
fn CGEventKeyboardSetUnicodeString(
event: crate::sys::CGEventRef,
length: c_ulong,
string: *const u16,
);
fn CGEventGetIntegerValueField(event: crate::sys::CGEventRef, field: CGEventField) -> i64;
fn CGEventSetIntegerValueField(event: crate::sys::CGEventRef, field: CGEventField, value: i64);
fn CGEventGetDoubleValueField(event: crate::sys::CGEventRef, field: CGEventField) -> f64;
fn CGEventSetDoubleValueField(event: crate::sys::CGEventRef, field: CGEventField, value: f64);
fn CGEventTapCreate(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
eventsOfInterest: CGEventMask,
callback: CGEventTapCallBackInternal,
userInfo: *const c_void,
) -> CFMachPortRef;
fn CGEventTapEnable(tap: CFMachPortRef, enable: bool);
fn CGEventSetLocation(event: crate::sys::CGEventRef, location: CGPoint);
}