summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-12-12 01:30:31 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-12-12 01:30:31 +0100
commitf86892c2639f0256a99d66bd34f40a572acc070c (patch)
tree06c02a62024198c40ad2fab12b6733d1dd695c74
parent11156b67778ce87a24611b918b60fe970b979755 (diff)
downloadvtcol-f86892c2639f0256a99d66bd34f40a572acc070c.tar.gz
bin: lib: implement setting state of individual LEDs
-rw-r--r--src/lib.rs26
-rw-r--r--src/vtcol.rs111
2 files changed, 120 insertions, 17 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0669b87..64cf6f3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -186,7 +186,10 @@ impl KbLedState
}
#[inline]
- pub fn revert(con: &Console) -> io::Result<()> { ioctl::kdsetled(con, None) }
+ pub fn revert(con: &Console) -> io::Result<()>
+ {
+ ioctl::kdsetled(con, None)
+ }
#[inline]
pub fn cap(&self) -> bool { (self.0 & 0x4) != 0 }
@@ -196,6 +199,27 @@ impl KbLedState
#[inline]
pub fn scr(&self) -> bool { (self.0 & 0x1) != 0 }
+
+ #[inline]
+ pub fn set_cap(&mut self, set: bool)
+ {
+ let bit = (set as u8) << 2;
+ self.0 = (self.0 & !bit) | bit;
+ }
+
+ #[inline]
+ pub fn set_num(&mut self, set: bool)
+ {
+ let bit = (set as u8) << 1;
+ self.0 = (self.0 & !bit) | bit;
+ }
+
+ #[inline]
+ pub fn set_scr(&mut self, set: bool)
+ {
+ let bit = set as u8;
+ self.0 = (self.0 & !bit) | bit;
+ }
}
impl fmt::Display for KbLedState
diff --git a/src/vtcol.rs b/src/vtcol.rs
index 738a622..0daccb0 100644
--- a/src/vtcol.rs
+++ b/src/vtcol.rs
@@ -23,8 +23,12 @@ enum LedJob
{
/** Get keyboard LED state. */
Get(bool),
- /** Set keyboard LED state; ``None`` indicates revert. */
- Set(Option<KbLedState>),
+ /** Revert to normal. */
+ Revert,
+ /** Set keyboard LED state of all leds at once. */
+ Set(KbLedState),
+ /** Set keyboard LED state of individual LEDs. */
+ SetIndividual(Option<bool>, Option<bool>, Option<bool>),
}
#[derive(Debug)]
@@ -230,7 +234,42 @@ impl<'a> Job
.long("u8")
.help("provide desired state as integer")
.takes_value(true)
- .required_unless_one(&["revert"])
+ .required_unless_one(&[
+ "revert", "caps", "num", "scroll",
+ ])
+ .conflicts_with_all(&[
+ "revert", "caps", "num", "scroll",
+ ])
+ .value_name("STATE"),
+ )
+ .arg(
+ Arg::with_name("caps")
+ .short("c")
+ .long("caps")
+ .help("[de]activate Caps Lock LED")
+ .takes_value(true)
+ .possible_values(&["on", "off"])
+ .conflicts_with_all(&["revert", "u8"])
+ .value_name("STATE"),
+ )
+ .arg(
+ Arg::with_name("num")
+ .short("n")
+ .long("num")
+ .help("[de]activate Num Lock LED")
+ .takes_value(true)
+ .possible_values(&["on", "off"])
+ .conflicts_with_all(&["revert", "u8"])
+ .value_name("STATE"),
+ )
+ .arg(
+ Arg::with_name("scroll")
+ .short("s")
+ .long("scroll")
+ .help("[de]activate Scroll Lock LED")
+ .takes_value(true)
+ .possible_values(&["on", "off"])
+ .conflicts_with_all(&["revert", "u8"])
.value_name("STATE"),
)
.arg(
@@ -239,7 +278,9 @@ impl<'a> Job
.long("revert")
.help("revert LED state to normal")
.takes_value(false)
- .conflicts_with("u8"),
+ .conflicts_with_all(&[
+ "u8", "caps", "num", "scroll",
+ ]),
),
),
);
@@ -358,11 +399,17 @@ impl<'a> Job
},
("set", Some(subm)) => {
if subm.is_present("revert") {
- return Ok(Self::Leds(LedJob::Set(None)));
+ return Ok(Self::Leds(LedJob::Revert));
+ }
+ if let Some(st) = subm.value_of("u8") {
+ let st: u8 = st.parse()?;
+ let st = KbLedState::try_from(st)?;
+ return Ok(Self::Leds(LedJob::Set(st)));
}
- let st: u8 = subm.value_of("u8").unwrap().parse()?;
- let st = KbLedState::try_from(st)?;
- Ok(Self::Leds(LedJob::Set(Some(st))))
+ let cap = subm.value_of("caps").map(|a| a == "on");
+ let num = subm.value_of("num").map(|a| a == "on");
+ let scr = subm.value_of("scroll").map(|a| a == "on");
+ Ok(Self::Leds(LedJob::SetIndividual(cap, num, scr)))
},
(junk, _) =>
Err(anyhow!(
@@ -441,7 +488,10 @@ impl<'a> Job
Self::Colors(ColorJob::Fade(from, to, ms, hz, clear)) =>
Self::fade(from, to, ms, hz, clear)?,
Self::Leds(LedJob::Get(raw)) => Self::get_leds(raw)?,
+ Self::Leds(LedJob::Revert) => Self::revert_leds()?,
Self::Leds(LedJob::Set(st)) => Self::set_leds(st)?,
+ Self::Leds(LedJob::SetIndividual(c, n, s)) =>
+ Self::set_leds_individual(c, n, s)?,
}
Ok(())
@@ -536,18 +586,47 @@ impl<'a> Job
}
/** Set the keyboard LED state. */
- fn set_leds(st: Option<KbLedState>) -> Result<()>
+ fn set_leds(st: KbLedState) -> Result<()>
{
let fd = Console::current()?;
vrb!("console fd: {}", fd);
- if let Some(st) = st {
- st.set(&fd)?;
- vrb!("applied");
- } else {
- KbLedState::revert(&fd)?;
- vrb!("reverted");
- }
+ st.set(&fd)?;
+ vrb!("applied");
+
+ Ok(())
+ }
+
+ /** Set the state of the given LEDs using the current state as base. */
+ fn set_leds_individual(
+ cap: Option<bool>,
+ num: Option<bool>,
+ scr: Option<bool>,
+ ) -> Result<()>
+ {
+ let fd = Console::current()?;
+ vrb!("console fd: {}", fd);
+
+ let mut st = KbLedState::get(&fd)?;
+
+ cap.map(|b| st.set_cap(b));
+ num.map(|b| st.set_num(b));
+ scr.map(|b| st.set_scr(b));
+
+ st.set(&fd)?;
+ vrb!("applied");
+
+ Ok(())
+ }
+
+ /** Revert the keyboard LED state. */
+ fn revert_leds() -> Result<()>
+ {
+ let fd = Console::current()?;
+ vrb!("console fd: {}", fd);
+
+ KbLedState::revert(&fd)?;
+ vrb!("reverted");
Ok(())
}