Start bringing up laptop detection

This commit is contained in:
Luke
2020-04-18 08:23:03 +12:00
parent a8a97bcece
commit 3788fbf095
10 changed files with 142 additions and 56 deletions

2
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

7
.idea/dictionaries/luke.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="luke">
<words>
<w>hotkey</w>
</words>
</dictionary>
</component>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/rog-core.iml" filepath="$PROJECT_DIR$/.idea/rog-core.iml" />
</modules>
</component>
</project>

24
.idea/rog-core.iml generated Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/rog-core/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rog-core/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rog-core/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/rog-core/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/rog-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rog-lib/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rog-lib/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/rog-lib/benches" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/rog-core/target" />
<excludeFolder url="file://$MODULE_DIR$/rog-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -4,21 +4,18 @@ use dbus::{
tree::{Factory, MethodErr},
};
use rog_lib::core::RogCore;
use rog_lib::hotkeys::*;
use std::error::Error;
use std::time::Duration;
use std::{cell::RefCell, rc::Rc};
pub struct Daemon {
rogcore: RogCore,
hotkeys: Box<dyn Laptop>,
}
impl Daemon {
pub fn new() -> Self {
Daemon {
rogcore: RogCore::new().expect("Could not start RogCore"),
hotkeys: Box::new(LaptopGX502GW::new()),
}
}
@@ -46,10 +43,8 @@ impl Daemon {
let bytes: Vec<u8> = m.msg.read1()?;
let s = format!("Wrote {:x?}", bytes);
let supported =
unsafe { (*daemon.as_ptr()).hotkeys.supported_modes() };
let mut daemon = daemon.borrow_mut();
match daemon.rogcore.aura_set_and_save(&bytes[..], supported) {
match daemon.borrow_mut().rogcore.aura_set_and_save(&bytes[..])
{
Ok(_) => {
let mret = m.msg.method_return().append1(s);
Ok(vec![mret])
@@ -73,14 +68,17 @@ impl Daemon {
connection.process(Duration::from_millis(1))?;
// READ KEYBOARD
// TODO: this needs to move to a thread, but there is unsafety
match daemon.borrow_mut().rogcore.poll_keyboard(&mut key_buf) {
let borrowed_daemon = daemon.borrow();
match borrowed_daemon.rogcore.poll_keyboard(&mut key_buf) {
Ok(read) => {
let hotkeys = unsafe { &mut (*daemon.as_ptr()).hotkeys };
// Doing this because the Laptop trait takes RogCore, but RogCore contains laptop
// and this makes the borrow checker unhappy, but it's safe for this
let mut rogcore = unsafe { &mut (*daemon.as_ptr()).rogcore };
let laptop = borrowed_daemon.rogcore.laptop();
if let Some(_count) = read {
if key_buf[0] == hotkeys.hotkey_group_byte() {
hotkeys.do_hotkey_action(&mut rogcore, key_buf[1]);
if key_buf[0] == laptop.hotkey_group_byte() {
laptop.do_hotkey_action(&mut rogcore, key_buf[1]);
}
}
}

View File

@@ -1,4 +1,3 @@
// TODO: use /sys/class/dmi/id/board_name to detect model
mod daemon;
use crate::daemon::*;

View File

@@ -1,8 +1,7 @@
use crate::aura::BuiltInModeByte;
use crate::config::Config;
use crate::error::AuraError;
use crate::{aura::BuiltInModeByte, config::Config, error::AuraError, laptops::*};
use gumdrop::Options;
use rusb::{DeviceHandle, Error};
use std::cell::{Ref, RefCell};
use std::str::FromStr;
use std::time::Duration;
@@ -57,19 +56,22 @@ pub struct RogCore {
handle: DeviceHandle<rusb::GlobalContext>,
initialised: bool,
led_interface_num: u8,
pub config: Config,
config: Config,
laptop: RefCell<Box<dyn Laptop>>,
}
impl RogCore {
pub fn new() -> Result<RogCore, Error> {
// TODO: make this more configurable
let mut handle = RogCore::get_device(0x0B05, 0x1866)?;
handle.set_active_configuration(0).unwrap_or(());
// TODO: use /sys/class/dmi/id/board_name to detect model
let laptop = LaptopGX502GW::new();
let config = handle.device().config_descriptor(0).unwrap();
let mut dev_handle = RogCore::get_device(laptop.usb_vendor(), laptop.usb_product())?;
dev_handle.set_active_configuration(0).unwrap_or(());
let dev_config = dev_handle.device().config_descriptor(0).unwrap();
// Interface with outputs
let mut led_interface_num = 0;
for iface in config.interfaces() {
for iface in dev_config.interfaces() {
for desc in iface.descriptors() {
for endpoint in desc.endpoint_descriptors() {
if endpoint.address() == 0x81 {
@@ -80,16 +82,29 @@ impl RogCore {
}
}
handle.set_auto_detach_kernel_driver(true).unwrap();
dev_handle.set_auto_detach_kernel_driver(true).unwrap();
Ok(RogCore {
handle,
handle: dev_handle,
initialised: false,
led_interface_num,
config: Config::default().read(),
laptop: RefCell::new(Box::new(laptop)),
})
}
pub fn laptop(&self) -> Ref<Box<dyn Laptop>> {
self.laptop.borrow()
}
pub fn config(&self) -> &Config {
&self.config
}
pub fn config_mut(&mut self) -> &mut Config {
&mut self.config
}
fn get_device(vendor: u16, product: u16) -> Result<DeviceHandle<rusb::GlobalContext>, Error> {
for device in rusb::devices().unwrap().iter() {
let device_desc = device.device_descriptor().unwrap();
@@ -138,13 +153,9 @@ impl RogCore {
Ok(bright)
}
pub fn aura_set_and_save(
&mut self,
bytes: &[u8],
supported: &[BuiltInModeByte],
) -> Result<(), Error> {
pub fn aura_set_and_save(&mut self, bytes: &[u8]) -> Result<(), Error> {
let mode = BuiltInModeByte::from(bytes[3]);
if supported.contains(&mode) || bytes[1] == 0xba {
if self.laptop().supported_modes().contains(&mode) || bytes[1] == 0xba {
let messages = [bytes];
self.aura_write_messages(&messages)?;
self.config.set_field_from(bytes);
@@ -163,7 +174,7 @@ impl RogCore {
// Ok(())
// }
pub fn poll_keyboard(&mut self, buf: &mut [u8; 32]) -> Result<Option<usize>, Error> {
pub fn poll_keyboard(&self, buf: &mut [u8; 32]) -> Result<Option<usize>, Error> {
match self
.handle
.read_interrupt(0x83, buf, Duration::from_micros(10))

View File

@@ -1,12 +1,29 @@
use crate::aura::BuiltInModeByte;
use crate::core::RogCore;
// ENV{POWER_SUPPLY_ONLINE}=="0", RUN+="gdbus call
// --session --dest org.gnome.SettingsDaemon.Power
// --object-path /org/gnome/SettingsDaemon/Power
// --method org.freedesktop.DBus.Properties.Set org.gnome.SettingsDaemon.Power.Screen Brightness '<int32 65>'"
const POWER_BUS_NAME: &'static str = "org.gnome.SettingsDaemon.Power";
const POWER_IFACE_NAME: &'static str = "org.gnome.SettingsDaemon.Power.Screen";
const POWER_PATH: &'static str = "/org/gnome/SettingsDaemon/Power";
pub trait Laptop {
fn do_hotkey_action(&self, core: &mut RogCore, key_byte: u8);
fn hotkey_group_byte(&self) -> u8;
fn supported_modes(&self) -> &[BuiltInModeByte];
fn usb_vendor(&self) -> u16;
fn usb_product(&self) -> u16;
fn board_name(&self) -> &str;
fn prod_family(&self) -> &str;
}
pub struct LaptopGX502GW {
usb_vendor: u16,
usb_product: u16,
board_name: &'static str,
prod_family: &'static str,
hotkey_group_byte: u8,
min_bright: u8,
max_bright: u8,
@@ -15,6 +32,10 @@ pub struct LaptopGX502GW {
impl LaptopGX502GW {
pub fn new() -> Self {
LaptopGX502GW {
usb_vendor: 0x0B05,
usb_product: 0x1866,
board_name: "GX502GW",
prod_family: "Zephyrus S",
hotkey_group_byte: 0x5a,
min_bright: 0x00,
max_bright: 0x03,
@@ -42,43 +63,37 @@ impl Laptop for LaptopGX502GW {
println!("ROG!");
}
GX502GWKeys::LedBrightUp => {
let mut bright = rogcore.config.brightness;
let mut bright = rogcore.config().brightness;
if bright < self.max_bright {
bright += 1;
rogcore.config.brightness = bright;
rogcore.config_mut().brightness = bright;
}
let bytes = RogCore::aura_brightness_bytes(bright).unwrap();
rogcore
.aura_set_and_save(&bytes, &self.supported_modes)
.unwrap();
rogcore.aura_set_and_save(&bytes).unwrap();
}
GX502GWKeys::LedBrightDown => {
let mut bright = rogcore.config.brightness;
let mut bright = rogcore.config().brightness;
if bright > self.min_bright {
bright -= 1;
rogcore.config.brightness = bright;
rogcore.config_mut().brightness = bright;
}
let bytes = RogCore::aura_brightness_bytes(bright).unwrap();
rogcore
.aura_set_and_save(&bytes, &self.supported_modes)
.unwrap();
rogcore.aura_set_and_save(&bytes).unwrap();
}
GX502GWKeys::AuraNext => {
let mut mode = rogcore.config.current_mode[3] + 1;
let mut mode = rogcore.config().current_mode[3] + 1;
if mode > 0x0c {
mode = 0x00
} else if mode == 0x09 {
mode = 0x0a
}
rogcore.config.current_mode[3] = mode;
if let Some(bytes) = rogcore.config.get_current() {
rogcore
.aura_set_and_save(&bytes, &self.supported_modes)
.unwrap();
rogcore.config_mut().current_mode[3] = mode;
if let Some(bytes) = rogcore.config_mut().get_current() {
rogcore.aura_set_and_save(&bytes).unwrap();
}
}
GX502GWKeys::AuraPrevious => {
let mut mode = rogcore.config.current_mode[3];
let mut mode = rogcore.config().current_mode[3];
if mode == 0x00 {
mode = 0x0c
} else if mode - 1 == 0x09 {
@@ -86,24 +101,40 @@ impl Laptop for LaptopGX502GW {
} else {
mode -= 1;
}
rogcore.config.current_mode[3] = mode;
if let Some(bytes) = rogcore.config.get_current() {
rogcore
.aura_set_and_save(&bytes, &self.supported_modes)
.unwrap();
rogcore.config.write();
rogcore.config_mut().current_mode[3] = mode;
if let Some(bytes) = rogcore.config_mut().get_current() {
rogcore.aura_set_and_save(&bytes).unwrap();
rogcore.config().write();
}
}
GX502GWKeys::ScreenBrightUp => {}
_ => {
if key_byte != 0 {
dbg!(&key_byte);
}
}
_ => {}
}
}
fn hotkey_group_byte(&self) -> u8 {
self.hotkey_group_byte
}
fn supported_modes(&self) -> &[BuiltInModeByte] {
&self.supported_modes
}
fn usb_vendor(&self) -> u16 {
self.usb_vendor
}
fn usb_product(&self) -> u16 {
self.usb_product
}
fn board_name(&self) -> &str {
&self.board_name
}
fn prod_family(&self) -> &str {
&self.prod_family
}
}
pub enum GX502GWKeys {

View File

@@ -4,4 +4,4 @@ pub mod cli_options;
pub mod config;
pub mod core;
mod error;
pub mod hotkeys;
pub mod laptops;