Skip to content

Commit

Permalink
test compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
pentamassiv committed Jan 7, 2024
1 parent 004c801 commit bbb5755
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 15 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ windows = { version = "0.51", features = [

[target.'cfg(target_os = "macos")'.dependencies]
core-graphics = { version = "0.23", features = ["highsierra"] }
icrate = { version = "0.1.0", features = ["AppKit_all"] }
icrate = { version = "0.1", features = [
"AppKit_all",
] } # AppKit_NSGraphicsContext
objc2 = { version = "0.5", features = ["relax-void-encoding"] }
foreign-types-shared = "0.3"

[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
Expand Down
33 changes: 28 additions & 5 deletions src/keycodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ pub enum Key {
/// backspace key
Backspace,
#[cfg(target_os = "linux")]
Begin,
#[cfg(target_os = "linux")]
Break,
#[cfg(target_os = "linux")]
Begin,
#[cfg(target_os = "macos")]
BrightnessDown,
#[cfg(target_os = "macos")]
BrightnessUp,
#[cfg(target_os = "windows")]
BrowserBack,
#[cfg(target_os = "windows")]
Expand All @@ -127,6 +131,10 @@ pub enum Key {
#[deprecated(since = "0.0.12", note = "now renamed to Meta")]
/// command key on macOS (super key on Linux, windows key on Windows)
Command,
#[cfg(target_os = "macos")]
ContrastUp,
#[cfg(target_os = "macos")]
ContrastDown,
/// control key
Control,
#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -169,6 +177,8 @@ pub enum Key {
Divide,
/// down arrow key
DownArrow,
#[cfg(target_os = "macos")]
Eject,
/// end key
End,
#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -322,6 +332,12 @@ pub enum Key {
IcoClear,
#[cfg(target_os = "windows")]
IcoHelp,
#[cfg(target_os = "macos")]
IlluminationDown,
#[cfg(target_os = "macos")]
IlluminationUp,
#[cfg(target_os = "macos")]
IlluminationToggle,
#[cfg(target_os = "windows")]
IMEOff,
#[cfg(target_os = "windows")]
Expand All @@ -345,6 +361,8 @@ pub enum Key {
#[cfg(target_os = "macos")]
/// Opens launchpad
Launchpad,
#[cfg(target_os = "macos")]
LaunchPanel,
#[cfg(target_os = "windows")]
LButton,
LControl,
Expand All @@ -359,12 +377,13 @@ pub enum Key {
LWin,
#[cfg(target_os = "windows")]
MButton,
#[cfg(any(target_os = "windows", target_os = "linux"))]
#[cfg(target_os = "macos")]
MediaFast,
MediaNextTrack,
#[cfg(any(target_os = "windows", target_os = "linux"))]
MediaPlayPause,
#[cfg(any(target_os = "windows", target_os = "linux"))]
MediaPrevTrack,
#[cfg(target_os = "macos")]
MediaRewind,
#[cfg(any(target_os = "windows", target_os = "linux"))]
MediaStop,
/// meta key (also known as "windows", "super", and "command")
Expand Down Expand Up @@ -502,6 +521,8 @@ pub enum Key {
Pause,
#[cfg(target_os = "windows")]
Play,
#[cfg(target_os = "macos")]
Power,
#[cfg(any(target_os = "windows", target_os = "linux"))]
Print,
#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -558,6 +579,8 @@ pub enum Key {
Undo,
/// up arrow key
UpArrow,
#[cfg(target_os = "macos")]
VidMirror,
VolumeDown,
VolumeMute,
VolumeUp,
Expand Down
212 changes: 203 additions & 9 deletions src/macos/macos_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ use std::{

use core_graphics::display::{CFIndex, CGDisplay, CGPoint};
use core_graphics::event::{
CGEvent, CGEventTapLocation, CGEventType, CGKeyCode, CGMouseButton, EventField, KeyCode,
ScrollEventUnit,
CGEvent, CGEventRef, CGEventTapLocation, CGEventType, CGKeyCode, CGMouseButton, EventField,
KeyCode, ScrollEventUnit,
};
use core_graphics::event_source::{CGEventSource, CGEventSourceStateID};
use icrate::AppKit;
use foreign_types_shared::ForeignTypeRef as _;
use icrate::{AppKit, AppKit::NSEvent};

use icrate::Foundation::NSPoint;
use log::{debug, error, info};
use objc2::msg_send;

use crate::{
Axis, Button, Coordinate, Direction, InputError, InputResult, Key, Keyboard, Mouse,
Expand Down Expand Up @@ -337,19 +341,100 @@ impl Keyboard for Enigo {
Ok(Some(()))
}

#[allow(clippy::too_many_lines)]
fn key(&mut self, key: Key, direction: Direction) -> InputResult<()> {
debug!("\x1b[93mkey(key: {key:?}, direction: {direction:?})\x1b[0m");
// Nothing to do
if key == Key::Unicode('\0') {
return Ok(());
}
match key {
Key::VolumeUp => {
debug!("special case for handling the VolumeUp key");
Enigo::special_keys(0, direction)?;
}
Key::VolumeDown => {
debug!("special case for handling the VolumeDown key");
Enigo::special_keys(1, direction)?;
}
Key::BrightnessUp => {
debug!("special case for handling the BrightnessUp key");
Enigo::special_keys(2, direction)?;
}
Key::BrightnessDown => {
debug!("special case for handling the BrightnessDown key");
Enigo::special_keys(3, direction)?;
}
Key::Power => {
debug!("special case for handling the VolumeMute key");
Enigo::special_keys(6, direction)?;
}
Key::VolumeMute => {
debug!("special case for handling the VolumeMute key");
Enigo::special_keys(7, direction)?;
}

let Ok(keycode) = CGKeyCode::try_from(key) else {
return Err(InputError::InvalidInput(
"virtual keycodes on macOS have to fit into u16",
));
};
self.raw(keycode, direction)?;
Key::ContrastUp => {
debug!("special case for handling the VolumeUp key");
Enigo::special_keys(11, direction)?;
}
Key::ContrastDown => {
debug!("special case for handling the VolumeDown key");
Enigo::special_keys(12, direction)?;
}
Key::LaunchPanel => {
debug!("special case for handling the MediaPlayPause key");
Enigo::special_keys(13, direction)?;
}
Key::Eject => {
debug!("special case for handling the MediaNextTrack key");
Enigo::special_keys(14, direction)?;
}
Key::VidMirror => {
debug!("special case for handling the MediaPrevTrack key");
Enigo::special_keys(15, direction)?;
}
Key::MediaPlayPause => {
debug!("special case for handling the MediaPlayPause key");
Enigo::special_keys(16, direction)?;
}
Key::MediaNextTrack => {
debug!("special case for handling the MediaNextTrack key");
Enigo::special_keys(17, direction)?;
}
Key::MediaPrevTrack => {
debug!("special case for handling the MediaPrevTrack key");
Enigo::special_keys(18, direction)?;
}
Key::MediaFast => {
debug!("special case for handling the MediaNextTrack key");
Enigo::special_keys(19, direction)?;
}
Key::MediaRewind => {
debug!("special case for handling the MediaPrevTrack key");
Enigo::special_keys(20, direction)?;
}
Key::IlluminationUp => {
debug!("special case for handling the MediaPrevTrack key");
Enigo::special_keys(21, direction)?;
}
Key::IlluminationDown => {
debug!("special case for handling the MediaNextTrack key");
Enigo::special_keys(22, direction)?;
}
Key::IlluminationToggle => {
debug!("special case for handling the MediaPrevTrack key");
Enigo::special_keys(23, direction)?;
}
_ => {
let Ok(keycode) = CGKeyCode::try_from(key) else {
return Err(InputError::InvalidInput(
"virtual keycodes on macOS have to fit into u16",
));
};
self.raw(keycode, direction)?;
}
}

// TODO: The list of keys will contain the key and also the associated keycode.
// They are a duplicate
Expand Down Expand Up @@ -487,6 +572,99 @@ impl Enigo {
debug!("nth_button_press: {nth_button_press}");
nth_button_press
}

fn special_keys(code: isize, direction: Direction) -> InputResult<()> {
if direction == Direction::Press || direction == Direction::Click {
let event = unsafe {
AppKit::NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
AppKit::NSEventTypeSystemDefined, // 14
NSPoint::ZERO,
0xa00, // NSEventModifierFlagCapsLock and NSEventModifierFlagOption
0.0,
0,
None,
8,
(code << 16) | (0xa << 8),
-1
)
};

if let Some(event) = event {
let cg_event = unsafe { Self::ns_event_cg_event(&event).to_owned() };
cg_event.post(CGEventTapLocation::HID);
} else {
return Err(InputError::Simulate(
"failed creating event to press special key",
));
}
}

if direction == Direction::Release || direction == Direction::Click {
let event = unsafe {
AppKit::NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
AppKit::NSEventTypeSystemDefined, // 14
NSPoint::ZERO,
0xb00, // NSEventModifierFlagCapsLock and NSEventModifierFlagOption
0.0,
0,
None,
8,
(code << 16) | (0xb << 8),
-1
)
};

if let Some(event) = event {
let cg_event = unsafe { Self::ns_event_cg_event(&event).to_owned() };
cg_event.post(CGEventTapLocation::HID);
} else {
return Err(InputError::Simulate(
"failed creating event to release special key",
));
}
}
Ok(())
/*
let event1 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xa00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xa << 8 as Int32))), data2: -1)
event1?.cgEvent?.post(tap: .cghidEventTap)
let event2 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xb00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xb << 8 as Int32))), data2: -1)
event2?.cgEvent?.post(tap: .cghidEventTap)
// Simulate illumination down
let code = NX_KEYTYPE_ILLUMINATION_DOWN
let event1 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xa00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xa << 8 as Int32))), data2: -1)
event1?.cgEvent?.post(tap: .cghidEventTap)
let event2 = NSEvent.otherEvent(with: .systemDefined, location: NSPoint.zero, modifierFlags: NSEventModifierFlags(rawValue: 0xb00), timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (Int((code << 16 as Int32) | (0xb << 8 as Int32))), data2: -1)
event2?.cgEvent?.post(tap: .cghidEventTap)
/* Mask of special keys that are posted as events */
#define NX_SPECIALKEY_POST_MASK \
((1 << NX_KEYTYPE_SOUND_UP) | (1 << NX_KEYTYPE_SOUND_DOWN) | \
(1 << NX_POWER_KEY) | (1 << NX_KEYTYPE_MUTE) | \
(1 << NX_KEYTYPE_BRIGHTNESS_UP) | (1 << NX_KEYTYPE_BRIGHTNESS_DOWN) | \
(1 << NX_KEYTYPE_CONTRAST_UP) | (1 << NX_KEYTYPE_CONTRAST_UP) | \
(1 << NX_KEYTYPE_LAUNCH_PANEL) | (1 << NX_KEYTYPE_EJECT) | \
(1 << NX_KEYTYPE_VIDMIRROR) | (1 << NX_KEYTYPE_PLAY) | \
(1 << NX_KEYTYPE_NEXT) | (1 << NX_KEYTYPE_PREVIOUS) | \
(1 << NX_KEYTYPE_FAST) | (1 << NX_KEYTYPE_REWIND) | \
(1 << NX_KEYTYPE_ILLUMINATION_UP) | \
(1 << NX_KEYTYPE_ILLUMINATION_DOWN) | \
(1 << NX_KEYTYPE_ILLUMINATION_TOGGLE) | 0)
*/
}

unsafe fn ns_event_cg_event(event: &NSEvent) -> &CGEventRef {
let ptr: *mut c_void = unsafe { msg_send![event, CGEvent] };
unsafe { CGEventRef::from_ptr(ptr.cast()) }
}
}

/// Converts a `Key` to a `CGKeyCode`
Expand Down Expand Up @@ -556,6 +734,22 @@ impl TryFrom<Key> for core_graphics::event::CGKeyCode {
v
}
Key::Super | Key::Command | Key::Windows | Key::Meta => KeyCode::COMMAND,
Key::BrightnessDown
| Key::BrightnessUp
| Key::ContrastUp
| Key::ContrastDown
| Key::Eject
| Key::IlluminationDown
| Key::IlluminationUp
| Key::IlluminationToggle
| Key::LaunchPanel
| Key::MediaFast
| Key::MediaNextTrack
| Key::MediaPlayPause
| Key::MediaPrevTrack
| Key::MediaRewind
| Key::Power
| Key::VidMirror => return Err(()),
};
Ok(key)
}
Expand Down

0 comments on commit bbb5755

Please sign in to comment.