Code cleanup

This commit is contained in:
Luke
2020-04-29 14:08:22 +12:00
parent f818ffa191
commit 4e78a5dbdd
8 changed files with 385 additions and 442 deletions

3
Cargo.lock generated
View File

@@ -660,9 +660,8 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
[[package]]
name = "rog-daemon"
version = "0.6.1"
version = "0.7.0"
dependencies = [
"aho-corasick",
"dbus",
"dbus-tokio",
"env_logger",

View File

@@ -1,7 +1,12 @@
[package]
name = "rog-daemon"
version = "0.6.1"
version = "0.7.0"
license = "MPL-2.0"
readme = "README.md"
authors = ["Luke <luke@ljones.dev>"]
repository = "https://github.com/flukejones/rog-core"
homepage = "https://github.com/flukejones/rog-core"
description = "A daemon app for ASUS GX502 and similar laptops to control missing features"
edition = "2018"
[lib]
@@ -14,25 +19,47 @@ path = "src/main.rs"
[dependencies]
rusb = "^0.5.5"
# cli crate
# cli and logging
gumdrop = "^0.8.0"
log = "^0.4.8"
env_logger = "^0.7.1"
# async
dbus = { version = "^0.8.2", features = ["futures"] }
dbus-tokio = "^0.5.1"
tokio = { version = "0.2.4", features = ["rt-threaded", "macros"] }
# serialisation
serde = "1.0"
serde_derive = "1.0"
toml = "0.5"
# used for backlight control mostly
# sysfs-class = "^0.1.2"
# Device control
# sysfs-class = "^0.1.2" # used for backlight control mostly
# cpu power management
intel-pstate = { git = "https://github.com/flukejones/intel-pstate" }
#
aho-corasick = "^0.7.10"
thiserror = "^1.0.15"
# virtualisation of HID, mainly for outputting consumer key codes
uhid-virt = "^0.0.4"
#keycode = "0.3"
#
thiserror = "^1.0.15"
[profile.release]
lto = true
debug = false
opt-level = 3
panic = "abort"
[profile.dev]
lto = true
debug = false
opt-level = 3
#panic = "abort"
[profile.bench]
lto = true
debug = false
opt-level = 3
#panic = "abort"

View File

@@ -6,7 +6,6 @@ use crate::{
error::AuraError,
virt_device::VirtKeys,
};
use aho_corasick::AhoCorasick;
use gumdrop::Options;
use log::{debug, error, info, warn};
use rusb::DeviceHandle;
@@ -50,12 +49,7 @@ pub(crate) struct RogCore {
}
impl RogCore {
pub(crate) fn new(
vendor: u16,
product: u16,
led_endpoint: u8,
key_endpoint: u8,
) -> Result<RogCore, AuraError> {
pub(crate) fn new(vendor: u16, product: u16, led_endpoint: u8) -> Result<RogCore, AuraError> {
let mut dev_handle = RogCore::get_device(vendor, product)?;
dev_handle.set_active_configuration(0).unwrap_or(());
@@ -65,11 +59,12 @@ impl RogCore {
for iface in dev_config.interfaces() {
for desc in iface.descriptors() {
for endpoint in desc.endpoint_descriptors() {
if endpoint.address() == key_endpoint {
debug!("INTERVAL: {:?}", endpoint.interval());
debug!("MAX: {:?}", endpoint.max_packet_size());
debug!("SYNC: {:?}", endpoint.sync_type());
debug!("TRANSFER_TYPE: {:?}", endpoint.transfer_type());
if endpoint.address() == led_endpoint {
info!("INTERVAL: {:?}", endpoint.interval());
info!("MAX_PKT_SIZE: {:?}", endpoint.max_packet_size());
info!("SYNC: {:?}", endpoint.sync_type());
info!("TRANSFER_TYPE: {:?}", endpoint.transfer_type());
info!("ENDPOINT: {:X?}", endpoint.address());
interface = desc.interface_number();
break;
}
@@ -110,7 +105,7 @@ impl RogCore {
};
let mut file = OpenOptions::new().write(true).open(path)?;
file.write(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
file.write_all(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
self.set_pstate_for_fan_mode(FanLevel::from(self.config.fan_mode))?;
info!("Reloaded last saved settings");
Ok(())
@@ -176,6 +171,26 @@ impl RogCore {
Ok(())
}
/// Write an effect block
///
/// `aura_effect_init` must be called any effect routine, and called only once.
pub async fn async_write_effect(
handle: &DeviceHandle<rusb::GlobalContext>,
endpoint: u8,
effect: Vec<Vec<u8>>,
) -> Result<(), AuraError> {
for row in effect.iter() {
match handle.write_interrupt(endpoint, row, Duration::from_millis(1)) {
Ok(_) => {}
Err(err) => match err {
rusb::Error::Timeout => {}
_ => error!("Failed to write LED interrupt: {:?}", err),
},
}
}
Ok(())
}
pub(crate) fn aura_set_and_save(
&mut self,
supported_modes: &[BuiltInModeByte],
@@ -205,9 +220,10 @@ impl RogCore {
if bright < max_bright {
bright += 1;
self.config.brightness = bright;
}
let bytes = aura_brightness_bytes(bright);
self.aura_set_and_save(supported_modes, &bytes)?;
info!("Increased LED brightness to {:#?}", bright);
}
Ok(())
}
@@ -220,9 +236,10 @@ impl RogCore {
if bright > min_bright {
bright -= 1;
self.config.brightness = bright;
}
let bytes = aura_brightness_bytes(bright);
self.aura_set_and_save(supported_modes, &bytes)?;
info!("Decreased LED brightness to {:#?}", bright);
}
Ok(())
}
@@ -300,7 +317,7 @@ impl RogCore {
n = 0;
}
info!("Fan mode stepped to: {:#?}", FanLevel::from(n));
fan_ctrl.write(format!("{:?}\n", n).as_bytes())?;
fan_ctrl.write_all(format!("{:?}\n", n).as_bytes())?;
self.set_pstate_for_fan_mode(FanLevel::from(n))?;
self.config.fan_mode = n;
self.config.write();
@@ -384,9 +401,8 @@ impl RogCore {
match Command::new("rfkill").arg("list").output() {
Ok(output) => {
if output.status.success() {
let patterns = &["yes"];
let ac = AhoCorasick::new(patterns);
if ac.earliest_find(output.stdout).is_some() {
if let Ok(out) = String::from_utf8(output.stdout) {
if out.contains(": yes") {
Command::new("rfkill")
.arg("unblock")
.arg("all")
@@ -396,7 +412,7 @@ impl RogCore {
|_| {},
);
} else {
let _ = Command::new("rfkill")
Command::new("rfkill")
.arg("block")
.arg("all")
.spawn()
@@ -405,6 +421,7 @@ impl RogCore {
|_| {},
);
}
}
} else {
warn!("Could not list rf devices");
}

View File

@@ -2,7 +2,10 @@ pub static DBUS_NAME: &'static str = "org.rogcore.Daemon";
pub static DBUS_PATH: &'static str = "/org/rogcore/Daemon";
pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon";
use crate::{core::RogCore, laptops::match_laptop};
use crate::{
core::RogCore,
laptops::{match_laptop, Laptop},
};
use dbus::{
nonblock::Process,
tree::{Factory, MTSync, Method, MethodErr, Tree},
@@ -87,6 +90,8 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
let supported = Vec::from(laptop.supported_modes());
// When any action occurs this time is reset
let mut time_mark = Instant::now();
let laptop_actions = laptop.get_runner();
loop {
connection.process_all();
@@ -110,7 +115,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
if let Ok(mut lock) = key_buf.try_lock() {
if let Some(bytes) = *lock {
// this takes at least 10ms per colour block
match laptop.run(&mut rogcore, bytes) {
match laptop_actions(&mut rogcore, bytes) {
Ok(_) => {}
Err(err) => {
error!("{:?}", err);

View File

@@ -1,154 +0,0 @@
use crate::aura::BuiltInModeByte;
use crate::core::RogCore;
use crate::error::AuraError;
use crate::virt_device::ConsumerKeys;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
use super::Laptop;
use log::info;
pub(super) struct LaptopGL753 {
usb_vendor: u16,
usb_product: u16,
board_name: &'static str,
prod_family: &'static str,
report_filter_bytes: [u8; 2],
min_led_bright: u8,
max_led_bright: u8,
led_endpoint: u8,
key_endpoint: u8,
supported_modes: [BuiltInModeByte; 3],
// backlight: Backlight,
}
impl LaptopGL753 {
pub(super) fn new() -> Self {
LaptopGL753 {
usb_vendor: 0x0B05,
usb_product: 0x1854,
// from `cat /sys/class/dmi/id/board_name`
board_name: "LaptopGL753VE",
// from `cat /sys/class/dmi/id/product_family`
prod_family: "",
report_filter_bytes: [0x5a, 0x02],
min_led_bright: 0x00,
max_led_bright: 0x03,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: [
BuiltInModeByte::Single,
BuiltInModeByte::Breathing,
BuiltInModeByte::Cycle,
],
// backlight: Backlight::new("intel_backlight").unwrap(),
}
}
}
impl LaptopGL753 {
fn do_keypress_actions(
&self,
rogcore: &mut RogCore,
key_buf: [u8; 32],
) -> Result<(), AuraError> {
match GL753Keys::from(key_buf[1]) {
GL753Keys::LedBrightUp => {
rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?;
}
GL753Keys::LedBrightDown => {
rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
}
GL753Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
}
GL753Keys::ScreenBrightDown => {
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
}
GL753Keys::Sleep => rogcore.suspend_with_systemd(),
GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GL753Keys::ScreenToggle => {
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
}
GL753Keys::TouchPadToggle => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x070;
rogcore.virt_keys().press(key);
}
GL753Keys::Rog => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x68; // XF86Tools? F13
rogcore.virt_keys().press(key);
}
GL753Keys::None => {
if key_buf[0] != 0x5A {
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
rogcore.virt_keys().press(key_buf);
}
}
}
Ok(())
}
}
impl Laptop for LaptopGL753 {
fn run(&self, rogcore: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError> {
self.do_keypress_actions(rogcore, key_buf)
}
fn led_endpoint(&self) -> u8 {
self.led_endpoint
}
fn key_endpoint(&self) -> u8 {
self.key_endpoint
}
fn key_filter(&self) -> &[u8] {
&self.report_filter_bytes
}
fn usb_vendor(&self) -> u16 {
self.usb_vendor
}
fn usb_product(&self) -> u16 {
self.usb_product
}
fn supported_modes(&self) -> &[BuiltInModeByte] {
&self.supported_modes
}
fn board_name(&self) -> &str {
&self.board_name
}
fn prod_family(&self) -> &str {
&self.prod_family
}
}
enum GL753Keys {
Rog = 0x38,
ScreenToggle = 0x35,
ScreenBrightDown = 0x10,
ScreenBrightUp = 0x20,
TouchPadToggle = 0x6b,
Sleep = 0x6C,
AirplaneMode = 0x88,
LedBrightUp = 0xC4,
LedBrightDown = 0xC5,
None,
}
impl From<u8> for GL753Keys {
fn from(byte: u8) -> Self {
match byte {
0x38 => GL753Keys::Rog,
0x35 => GL753Keys::ScreenToggle,
0x10 => GL753Keys::ScreenBrightDown,
0x20 => GL753Keys::ScreenBrightUp,
0x6b => GL753Keys::TouchPadToggle,
0x6C => GL753Keys::Sleep,
0x88 => GL753Keys::AirplaneMode,
0xC4 => GL753Keys::LedBrightUp,
0xC5 => GL753Keys::LedBrightDown,
_ => GL753Keys::None,
}
}
}

View File

@@ -1,182 +0,0 @@
use crate::aura::BuiltInModeByte;
use crate::core::RogCore;
use crate::error::AuraError;
use crate::virt_device::ConsumerKeys;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
use super::Laptop;
use log::{info, warn};
pub(super) struct LaptopGX502 {
usb_vendor: u16,
usb_product: u16,
board_name: &'static str,
prod_family: &'static str,
report_filter_bytes: [u8; 2],
min_led_bright: u8,
max_led_bright: u8,
led_endpoint: u8,
key_endpoint: u8,
supported_modes: [BuiltInModeByte; 12],
//backlight: Backlight,
}
impl LaptopGX502 {
pub(super) fn new() -> Self {
// Find backlight
LaptopGX502 {
usb_vendor: 0x0B05,
usb_product: 0x1866,
// from `cat /sys/class/dmi/id/board_name`
board_name: "GX502GW",
// from `cat /sys/class/dmi/id/product_family`
prod_family: "Zephyrus S",
report_filter_bytes: [0x5a, 0x02],
min_led_bright: 0x00,
max_led_bright: 0x03,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: [
BuiltInModeByte::Single,
BuiltInModeByte::Breathing,
BuiltInModeByte::Cycle,
BuiltInModeByte::Rainbow,
BuiltInModeByte::Rain,
BuiltInModeByte::Random,
BuiltInModeByte::Highlight,
BuiltInModeByte::Laser,
BuiltInModeByte::Ripple,
BuiltInModeByte::Pulse,
BuiltInModeByte::ThinZoomy,
BuiltInModeByte::WideZoomy,
],
//backlight: Backlight::new("intel_backlight").unwrap(),
}
}
}
impl LaptopGX502 {
fn do_keypress_actions(
&self,
rogcore: &mut RogCore,
key_buf: [u8; 32],
) -> Result<(), AuraError> {
match GX502Keys::from(key_buf[1]) {
GX502Keys::LedBrightUp => {
rogcore.aura_bright_inc(&self.supported_modes, self.max_led_bright)?;
}
GX502Keys::LedBrightDown => {
rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
}
GX502Keys::AuraNext => rogcore.aura_mode_next(&self.supported_modes)?,
GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&self.supported_modes)?,
GX502Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
} //self.backlight.step_up(),
GX502Keys::ScreenBrightDown => {
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
} //self.backlight.step_down(),
GX502Keys::Sleep => rogcore.suspend_with_systemd(),
GX502Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GX502Keys::MicToggle => {}
GX502Keys::Fan => {
rogcore.fan_mode_step().unwrap_or_else(|err| {
warn!("Couldn't toggle fan mode: {:?}", err);
});
}
GX502Keys::ScreenToggle => {
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
}
GX502Keys::TouchPadToggle => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x070;
rogcore.virt_keys().press(key);
}
GX502Keys::Rog => {
//rogcore.aura_effect_init()?;
//rogcore.aura_write_effect(&self.per_key_led)?;
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x68; // XF86Tools? F13
rogcore.virt_keys().press(key);
}
GX502Keys::None => {
if key_buf[0] != 0x5A {
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
rogcore.virt_keys().press(key_buf);
}
}
}
Ok(())
}
}
impl Laptop for LaptopGX502 {
fn run(&self, rogcore: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError> {
self.do_keypress_actions(rogcore, key_buf)
}
fn led_endpoint(&self) -> u8 {
self.led_endpoint
}
fn key_endpoint(&self) -> u8 {
self.key_endpoint
}
fn key_filter(&self) -> &[u8] {
&self.report_filter_bytes
}
fn usb_vendor(&self) -> u16 {
self.usb_vendor
}
fn usb_product(&self) -> u16 {
self.usb_product
}
fn supported_modes(&self) -> &[BuiltInModeByte] {
&self.supported_modes
}
fn board_name(&self) -> &str {
&self.board_name
}
fn prod_family(&self) -> &str {
&self.prod_family
}
}
enum GX502Keys {
Rog = 0x38,
MicToggle = 0x7C,
Fan = 0xAE,
ScreenToggle = 0x35,
ScreenBrightDown = 0x10,
ScreenBrightUp = 0x20,
TouchPadToggle = 0x6b,
Sleep = 0x6C,
AirplaneMode = 0x88,
LedBrightUp = 0xC4,
LedBrightDown = 0xC5,
AuraPrevious = 0xB2,
AuraNext = 0xB3,
None,
}
impl From<u8> for GX502Keys {
fn from(byte: u8) -> Self {
match byte {
0x38 => GX502Keys::Rog,
0x7C => GX502Keys::MicToggle,
0xAE => GX502Keys::Fan,
0x35 => GX502Keys::ScreenToggle,
0x10 => GX502Keys::ScreenBrightDown,
0x20 => GX502Keys::ScreenBrightUp,
0x6b => GX502Keys::TouchPadToggle,
0x6C => GX502Keys::Sleep,
0x88 => GX502Keys::AirplaneMode,
0xC4 => GX502Keys::LedBrightUp,
0xC5 => GX502Keys::LedBrightDown,
0xB2 => GX502Keys::AuraPrevious,
0xB3 => GX502Keys::AuraNext,
_ => GX502Keys::None,
}
}
}

View File

@@ -2,53 +2,68 @@ use crate::aura::BuiltInModeByte;
use crate::core::RogCore;
use crate::error::AuraError;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
use log::info;
use crate::virt_device::ConsumerKeys;
use log::{info, warn};
// GL753VE == 0x1854, 4 zone keyboard
mod gl753;
use gl753::LaptopGL753;
// 0x1866, per-key LEDs, media-keys split from vendor specific
mod gx502;
use gx502::LaptopGX502;
pub(crate) fn match_laptop() -> Box<dyn Laptop> {
pub(crate) fn match_laptop() -> LaptopBase {
for device in rusb::devices().unwrap().iter() {
let device_desc = device.device_descriptor().unwrap();
if device_desc.vendor_id() == 0x0b05 {
match device_desc.product_id() {
0x1869 | 0x1866 => {
info!("Found GX502 or similar");
return Box::new(LaptopGX502::new());
return LaptopBase {
usb_vendor: 0x0B05,
usb_product: 0x1866,
report_filter_bytes: vec![0x5a, 0x02],
min_led_bright: 0x00,
max_led_bright: 0x03,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: vec![
BuiltInModeByte::Single,
BuiltInModeByte::Breathing,
BuiltInModeByte::Cycle,
BuiltInModeByte::Rainbow,
BuiltInModeByte::Rain,
BuiltInModeByte::Random,
BuiltInModeByte::Highlight,
BuiltInModeByte::Laser,
BuiltInModeByte::Ripple,
BuiltInModeByte::Pulse,
BuiltInModeByte::ThinZoomy,
BuiltInModeByte::WideZoomy,
],
//backlight: Backlight::new("intel_backlight").unwrap(),
};
}
0x1854 => {
info!("Found GL753 or similar");
return Box::new(LaptopGL753::new());
return LaptopBase {
usb_vendor: 0x0B05,
usb_product: 0x1854,
report_filter_bytes: vec![0x5a, 0x02],
min_led_bright: 0x00,
max_led_bright: 0x03,
//from `lsusb -vd 0b05:1866`
led_endpoint: 0x04,
//from `lsusb -vd 0b05:1866`
key_endpoint: 0x83,
supported_modes: vec![
BuiltInModeByte::Single,
BuiltInModeByte::Breathing,
BuiltInModeByte::Cycle,
],
// backlight: Backlight::new("intel_backlight").unwrap(),
};
}
_ => {}
}
}
}
panic!("could not match laptop");
// let dmi = sysfs_class::DmiId::default();
// let board_name = dmi.board_name().unwrap();
// match &board_name.as_str()[..5] {
// // TODO: FX503VD - 0x1869,
// // These two models seem to have the same characteristics
// "GX502" | "GA502" | "GU502" => {
// info!("Found GX502 or GA502 series");
// Box::new(LaptopGX502::new())
// }
// // LED should work for this, but unsure of keys
// "GL753" => {
// info!("Found GL753 series");
// Box::new(LaptopGL753::new())
// }
// _ => {
// panic!("could not match laptop");
// }
// }
}
/// All laptop models should implement this trait. The role of a `Laptop` is to
@@ -63,13 +78,235 @@ pub(crate) fn match_laptop() -> Box<dyn Laptop> {
/// If using the `keycode` crate to build keyboard input, the report must be prefixed
/// with the report ID (usually `0x01` for the virtual keyboard).
pub(crate) trait Laptop {
fn board_name(&self) -> &str;
fn prod_family(&self) -> &str;
fn run(&self, core: &mut RogCore, key_buf: [u8; 32]) -> Result<(), AuraError>;
fn get_runner(&self) -> Box<dyn Fn(&mut RogCore, [u8; 32]) -> Result<(), AuraError>>;
fn led_endpoint(&self) -> u8;
fn key_endpoint(&self) -> u8;
fn key_filter(&self) -> &[u8];
fn usb_vendor(&self) -> u16;
fn usb_product(&self) -> u16;
// required for profiles which match more than one laptop
fn set_usb_product(&mut self, product: u16);
fn supported_modes(&self) -> &[BuiltInModeByte];
}
pub(crate) type LaptopRunner = dyn Fn(&mut RogCore, [u8; 32]) -> Result<(), AuraError>;
pub(super) struct LaptopBase {
usb_vendor: u16,
usb_product: u16,
report_filter_bytes: Vec<u8>,
min_led_bright: u8,
max_led_bright: u8,
led_endpoint: u8,
key_endpoint: u8,
supported_modes: Vec<BuiltInModeByte>,
//backlight: Backlight,
}
impl Laptop for LaptopBase {
fn get_runner(&self) -> Box<LaptopRunner> {
match self.usb_product {
0x1869 | 0x1866 => self.gx502_runner(),
0x1854 => self.gl753_runner(),
_ => panic!("No runner available for this device"),
}
}
fn led_endpoint(&self) -> u8 {
self.led_endpoint
}
fn key_endpoint(&self) -> u8 {
self.key_endpoint
}
fn key_filter(&self) -> &[u8] {
&self.report_filter_bytes
}
fn usb_vendor(&self) -> u16 {
self.usb_vendor
}
fn usb_product(&self) -> u16 {
self.usb_product
}
fn set_usb_product(&mut self, product: u16) {
self.usb_product = product;
}
fn supported_modes(&self) -> &[BuiltInModeByte] {
&self.supported_modes
}
}
impl LaptopBase {
// 0x1866, per-key LEDs, media-keys split from vendor specific
fn gx502_runner(&self) -> Box<LaptopRunner> {
let max_led_bright = self.max_led_bright;
let min_led_bright = self.min_led_bright;
let supported_modes = self.supported_modes.to_owned();
let function = move |rogcore: &mut RogCore, key_buf: [u8; 32]| {
match GX502Keys::from(key_buf[1]) {
GX502Keys::LedBrightUp => {
rogcore.aura_bright_inc(&supported_modes, max_led_bright)?;
}
GX502Keys::LedBrightDown => {
rogcore.aura_bright_dec(&supported_modes, min_led_bright)?;
}
GX502Keys::AuraNext => rogcore.aura_mode_next(&supported_modes)?,
GX502Keys::AuraPrevious => rogcore.aura_mode_prev(&supported_modes)?,
GX502Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
} //self.backlight.step_up(),
GX502Keys::ScreenBrightDown => {
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
} //self.backlight.step_down(),
GX502Keys::Sleep => rogcore.suspend_with_systemd(),
GX502Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GX502Keys::MicToggle => {}
GX502Keys::Fan => {
rogcore.fan_mode_step().unwrap_or_else(|err| {
warn!("Couldn't toggle fan mode: {:?}", err);
});
}
GX502Keys::ScreenToggle => {
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
}
GX502Keys::TouchPadToggle => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x070;
rogcore.virt_keys().press(key);
}
GX502Keys::Rog => {
//rogcore.aura_effect_init()?;
//rogcore.aura_write_effect(&self.per_key_led)?;
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x68; // XF86Tools? F13
rogcore.virt_keys().press(key);
}
GX502Keys::None => {
if key_buf[0] != 0x5A {
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
rogcore.virt_keys().press(key_buf);
}
}
}
Ok(())
};
Box::new(function)
}
// GL753VE == 0x1854, 4 zone keyboard
fn gl753_runner(&self) -> Box<LaptopRunner> {
let max_led_bright = self.max_led_bright;
let min_led_bright = self.min_led_bright;
let supported_modes = self.supported_modes.to_owned();
let function = move |rogcore: &mut RogCore, key_buf: [u8; 32]| {
match GL753Keys::from(key_buf[1]) {
GL753Keys::LedBrightUp => {
rogcore.aura_bright_inc(&supported_modes, max_led_bright)?;
}
GL753Keys::LedBrightDown => {
rogcore.aura_bright_dec(&supported_modes, min_led_bright)?;
}
GL753Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
}
GL753Keys::ScreenBrightDown => {
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
}
GL753Keys::Sleep => rogcore.suspend_with_systemd(),
GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GL753Keys::ScreenToggle => {
rogcore.virt_keys().press(ConsumerKeys::BacklightTog.into());
}
GL753Keys::TouchPadToggle => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x070;
rogcore.virt_keys().press(key);
}
GL753Keys::Rog => {
let mut key = [0u8; 32];
key[0] = 0x01;
key[3] = 0x68; // XF86Tools? F13
rogcore.virt_keys().press(key);
}
GL753Keys::None => {
if key_buf[0] != 0x5A {
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
rogcore.virt_keys().press(key_buf);
}
}
}
Ok(())
};
Box::new(function)
}
}
pub(crate) enum GX502Keys {
Rog = 0x38,
MicToggle = 0x7C,
Fan = 0xAE,
ScreenToggle = 0x35,
ScreenBrightDown = 0x10,
ScreenBrightUp = 0x20,
TouchPadToggle = 0x6b,
Sleep = 0x6C,
AirplaneMode = 0x88,
LedBrightUp = 0xC4,
LedBrightDown = 0xC5,
AuraPrevious = 0xB2,
AuraNext = 0xB3,
None,
}
impl From<u8> for GX502Keys {
fn from(byte: u8) -> Self {
match byte {
0x38 => GX502Keys::Rog,
0x7C => GX502Keys::MicToggle,
0xAE => GX502Keys::Fan,
0x35 => GX502Keys::ScreenToggle,
0x10 => GX502Keys::ScreenBrightDown,
0x20 => GX502Keys::ScreenBrightUp,
0x6b => GX502Keys::TouchPadToggle,
0x6C => GX502Keys::Sleep,
0x88 => GX502Keys::AirplaneMode,
0xC4 => GX502Keys::LedBrightUp,
0xC5 => GX502Keys::LedBrightDown,
0xB2 => GX502Keys::AuraPrevious,
0xB3 => GX502Keys::AuraNext,
_ => GX502Keys::None,
}
}
}
enum GL753Keys {
Rog = 0x38,
ScreenToggle = 0x35,
ScreenBrightDown = 0x10,
ScreenBrightUp = 0x20,
TouchPadToggle = 0x6b,
Sleep = 0x6C,
AirplaneMode = 0x88,
LedBrightUp = 0xC4,
LedBrightDown = 0xC5,
None,
}
impl From<u8> for GL753Keys {
fn from(byte: u8) -> Self {
match byte {
0x38 => GL753Keys::Rog,
0x35 => GL753Keys::ScreenToggle,
0x10 => GL753Keys::ScreenBrightDown,
0x20 => GL753Keys::ScreenBrightUp,
0x6b => GL753Keys::TouchPadToggle,
0x6C => GL753Keys::Sleep,
0x88 => GL753Keys::AirplaneMode,
0xC4 => GL753Keys::LedBrightUp,
0xC5 => GL753Keys::LedBrightDown,
_ => GL753Keys::None,
}
}
}

View File

@@ -10,7 +10,7 @@ use env_logger::{Builder, Target};
use gumdrop::Options;
use log::LevelFilter;
static VERSION: &'static str = "0.6.1";
static VERSION: &'static str = "0.7.0";
#[derive(Debug, Options)]
struct CLIStart {
@@ -42,7 +42,7 @@ struct LedModeCommand {
#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut builder = Builder::from_env("ROGCORE_LOG");
let mut builder = Builder::new();
builder.target(Target::Stdout);
builder.format_timestamp(None);
builder.filter(None, LevelFilter::Info).init();
@@ -55,8 +55,7 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Version: {}", VERSION);
}
match parsed.command {
Some(Command::LedMode(mode)) => {
if let Some(Command::LedMode(mode)) = parsed.command {
if let Some(command) = mode.command {
// Check for special modes here, eg, per-key or multi-zone
match command {
@@ -73,15 +72,10 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
}
None => {}
}
match parsed.bright {
Some(brightness) => {
if let Some(brightness) = parsed.bright {
let bytes = aura_brightness_bytes(brightness.level());
dbus_led_builtin_write(&bytes)?;
}
_ => {}
}
Ok(())
}