summaryrefslogtreecommitdiff
path: root/src/vtcol.rs
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-12-12 23:17:29 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-12-12 23:19:45 +0100
commit92f35f8e90199e4d9dfbcc545be456f4c2d7a1ce (patch)
tree99decf47747cc32983dd0a149600e7e7256866ff /src/vtcol.rs
parent468341393863e35bec170528ab5a99ee26acb85a (diff)
downloadvtcol-92f35f8e90199e4d9dfbcc545be456f4c2d7a1ce.tar.gz
lib: implement “kb flags”
A const-genericized version of the “kb leds” implementation. Does seem to consistently run into EINVAL no matter what flags we provide. Also incomplete as KDGKBLED / KDSKBLED pack more info into higher bits of their argument.
Diffstat (limited to 'src/vtcol.rs')
-rw-r--r--src/vtcol.rs260
1 files changed, 242 insertions, 18 deletions
diff --git a/src/vtcol.rs b/src/vtcol.rs
index b24937b..a3ff57b 100644
--- a/src/vtcol.rs
+++ b/src/vtcol.rs
@@ -1,6 +1,6 @@
pub mod lib;
-use vtcol::{Console, Fade, KbLedState, Palette, Scheme};
+use vtcol::{Console, Fade, KbLedFlags, KbLedState, Palette, Scheme};
use anyhow::{anyhow, Result};
use std::{io::{self, BufWriter},
@@ -127,6 +127,105 @@ impl LedJob
} /* [impl LedJob] */
#[derive(Debug)]
+enum FlagJob
+{
+ /** Get keyboard flags. */
+ Get(bool),
+ /** Set all keyboard flags at once. */
+ Set(KbLedFlags),
+ /** Set keyboard LED state of individual LEDs. */
+ SetIndividual(Option<bool>, Option<bool>, Option<bool>),
+}
+
+impl FlagJob
+{
+ /** Get the keyboard flags (modifier locks). */
+ fn get(con: Option<String>, raw: bool) -> Result<()>
+ {
+ let fd = open_console(con.as_deref())?;
+ vrb!("console fd: {}", fd);
+
+ let leds = KbLedFlags::get(&fd)?;
+
+ if raw {
+ println!("{}", u8::from(leds));
+ } else {
+ println!("{}", leds);
+ }
+
+ Ok(())
+ }
+
+ /** Set the keyboard flags. */
+ fn set(con: Option<String>, st: KbLedFlags) -> Result<()>
+ {
+ let fd = open_console(con.as_deref())?;
+ vrb!("console fd: {}", fd);
+
+ st.set(&fd)?;
+ vrb!("applied");
+
+ Ok(())
+ }
+
+ /** Set / unset keyboard flags using the current as base. */
+ fn set_individual(
+ con: Option<String>,
+ cap: Option<bool>,
+ num: Option<bool>,
+ scr: Option<bool>,
+ ) -> Result<()>
+ {
+ let fd = open_console(con.as_deref())?;
+ vrb!("console fd: {}", fd);
+
+ let mut st = KbLedFlags::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(())
+ }
+} /*[impl FlagJob] */
+
+impl Run for FlagJob
+{
+ fn run(self, console: Option<String>) -> Result<()>
+ {
+ match self {
+ Self::Get(raw) => Self::get(console, raw),
+ Self::Set(flags) => Self::set(console, flags),
+ Self::SetIndividual(c, n, s) =>
+ Self::set_individual(console, c, n, s),
+ }
+ }
+} /* [impl Run for FlagJob] */
+
+#[derive(Debug)]
+enum KbJob
+{
+ /** LED state ops. */
+ Leds(LedJob),
+ /** Flags. */
+ Flags(FlagJob),
+}
+
+impl Run for KbJob
+{
+ fn run(self, console: Option<String>) -> Result<()>
+ {
+ match self {
+ Self::Leds(leds) => leds.run(console),
+ Self::Flags(flags) => flags.run(console),
+ }
+ }
+} /* [impl Run for KbJob] */
+
+#[derive(Debug)]
enum ColorJob
{
/** List available schemes. */
@@ -286,7 +385,7 @@ enum Subcmd
/** Console palette ops. */
Colors(ColorJob),
/** Keyboard LED ops. */
- Leds(LedJob),
+ Kb(KbJob),
}
#[derive(Debug)]
@@ -545,6 +644,85 @@ impl<'a> Job
]),
),
),
+ )
+ .subcommand(
+ SubCommand::with_name("flags")
+ .about(
+ "operations regarding keyboard flags \
+ (modifier locks)",
+ )
+ .subcommand(
+ SubCommand::with_name("get")
+ .about("get flags")
+ .arg(
+ Arg::with_name("u8")
+ .short("8")
+ .long("u8")
+ .help("output raw flags as integer")
+ .takes_value(false),
+ ),
+ )
+ .subcommand(
+ SubCommand::with_name("set")
+ .about("set flags")
+ .arg(
+ Arg::with_name("u8")
+ .short("8")
+ .long("u8")
+ .help(
+ "provide desired flags as
+ integer",
+ )
+ .takes_value(true)
+ .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 flag")
+ .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 flag")
+ .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 flag",
+ )
+ .takes_value(true)
+ .possible_values(&["on", "off"])
+ .conflicts_with_all(&[
+ "revert", "u8",
+ ])
+ .value_name("STATE"),
+ ),
+ ),
),
);
@@ -681,13 +859,16 @@ impl<'a> Job
match subm.subcommand() {
("get", Some(subm)) => {
let raw = subm.is_present("u8");
- Ok(Self(con, Subcmd::Leds(LedJob::Get(raw))))
+ Ok(Self(
+ con,
+ Subcmd::Kb(KbJob::Leds(LedJob::Get(raw))),
+ ))
},
("set", Some(subm)) => {
if subm.is_present("revert") {
return Ok(Self(
con,
- Subcmd::Leds(LedJob::Revert),
+ Subcmd::Kb(KbJob::Leds(LedJob::Revert)),
));
}
if let Some(st) = subm.value_of("u8") {
@@ -695,7 +876,50 @@ impl<'a> Job
let st = KbLedState::try_from(st)?;
return Ok(Self(
con,
- Subcmd::Leds(LedJob::Set(st)),
+ Subcmd::Kb(KbJob::Leds(LedJob::Set(
+ 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(
+ con,
+ Subcmd::Kb(KbJob::Leds(
+ LedJob::SetIndividual(cap, num, scr),
+ )),
+ ))
+ },
+ (leds_junk, _) =>
+ Err(anyhow!(
+ "invalid sub-sub-subcommand to kb leds: \
+ [{}]; try ``{} kb leds --help``",
+ leds_junk,
+ clap::crate_name!()
+ )),
+ },
+ ("flags", Some(subm)) =>
+ match subm.subcommand() {
+ ("get", Some(subm)) => {
+ let raw = subm.is_present("u8");
+ Ok(Self(
+ con,
+ Subcmd::Kb(KbJob::Flags(FlagJob::Get(raw))),
+ ))
+ },
+ ("set", Some(subm)) => {
+ if let Some(st) = subm.value_of("u8") {
+ let st: u8 = st.parse()?;
+ let st = KbLedFlags::try_from(st)?;
+ return Ok(Self(
+ con,
+ Subcmd::Kb(KbJob::Flags(FlagJob::Set(
+ st,
+ ))),
));
}
let cap =
@@ -706,32 +930,32 @@ impl<'a> Job
subm.value_of("scroll").map(|a| a == "on");
Ok(Self(
con,
- Subcmd::Leds(LedJob::SetIndividual(
- cap, num, scr,
+ Subcmd::Kb(KbJob::Flags(
+ FlagJob::SetIndividual(cap, num, scr),
)),
))
},
- (junk, _) =>
+ (flags_junk, _) =>
Err(anyhow!(
- "invalid sub-subcommand to leds: [{}]; \
- try ``{} leds --help``",
- junk,
+ "invalid sub-sub-subcommand to kb flags: \
+ [{}]; try ``{} kb flags --help``",
+ flags_junk,
clap::crate_name!()
)),
},
- (leds_junk, _) =>
+ (kb_junk, _) =>
Err(anyhow!(
- "invalid subcommand to kb leds [{}]; try ``{} \
+ "invalid sub-subcommand to kb [{}]; try ``{} kb \
--help``",
- leds_junk,
+ kb_junk,
clap::crate_name!()
)),
},
- (kb_junk, _) =>
+ (junk, _) =>
Err(anyhow!(
- "invalid subcommand to kb [{}]; try ``{} --help``",
- kb_junk,
+ "invalid subcommand [{}]; try ``{} --help``",
+ junk,
clap::crate_name!()
)),
}
@@ -749,7 +973,7 @@ impl<'a> Job
let Job(con, cmd) = self;
match cmd {
Subcmd::Colors(cols) => cols.run(con)?,
- Subcmd::Leds(leds) => leds.run(con)?,
+ Subcmd::Kb(kb) => kb.run(con)?,
}
Ok(())