diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/vtcol.rs | 180 | 
2 files changed, 118 insertions, 64 deletions
| @@ -921,7 +921,7 @@ impl Console          Ok(fd)      } -    fn from_path<P: AsRef<Path>>(path: P) -> io::Result<Self> +    pub fn from_path<P: AsRef<Path>>(path: P) -> io::Result<Self>      {          let p =              std::ffi::CString::new(path.as_ref().to_str().unwrap()).unwrap(); diff --git a/src/vtcol.rs b/src/vtcol.rs index dcc7820..89cc162 100644 --- a/src/vtcol.rs +++ b/src/vtcol.rs @@ -18,9 +18,18 @@ macro_rules! vrb {      )}  } +/** Helper for choosing the console. Defaults to the current one if +none is explicitly supplied. */ +#[inline] +fn open_console(path: Option<&str>) -> io::Result<Console> +{ +    path.map(Console::from_path).unwrap_or_else(|| Console::current()) +} + +/** Trait for subcommands to implement. */  trait Run  { -    fn run(self) -> Result<()>; +    fn run(self, console: Option<String>) -> Result<()>;  }  #[derive(Debug)] @@ -38,13 +47,14 @@ enum LedJob  impl Run for LedJob  { -    fn run(self) -> Result<()> +    fn run(self, console: Option<String>) -> Result<()>      {          match self { -            Self::Get(raw) => Self::get(raw), -            Self::Revert => Self::revert(), -            Self::Set(st) => Self::set(st), -            Self::SetIndividual(c, n, s) => Self::set_individual(c, n, s), +            Self::Get(raw) => Self::get(console, raw), +            Self::Revert => Self::revert(console), +            Self::Set(st) => Self::set(console, st), +            Self::SetIndividual(c, n, s) => +                Self::set_individual(console, c, n, s),          }      }  } /* [impl Run for LedJob] */ @@ -52,9 +62,9 @@ impl Run for LedJob  impl LedJob  {      /** Get the keyboard LED state. */ -    fn get(raw: bool) -> Result<()> +    fn get(con: Option<String>, raw: bool) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          let leds = KbLedState::get(&fd)?; @@ -69,9 +79,9 @@ impl LedJob      }      /** Set the keyboard LED state. */ -    fn set(st: KbLedState) -> Result<()> +    fn set(con: Option<String>, st: KbLedState) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          st.set(&fd)?; @@ -82,12 +92,13 @@ impl LedJob      /** Set the state of the given LEDs using the current state as base. */      fn set_individual( +        con: Option<String>,          cap: Option<bool>,          num: Option<bool>,          scr: Option<bool>,      ) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          let mut st = KbLedState::get(&fd)?; @@ -103,9 +114,9 @@ impl LedJob      }      /** Revert the keyboard LED state. */ -    fn revert() -> Result<()> +    fn revert(con: Option<String>) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          KbLedState::revert(&fd)?; @@ -134,16 +145,16 @@ enum ColorJob  impl Run for ColorJob  { -    fn run(self) -> Result<()> +    fn run(self, console: Option<String>) -> Result<()>      {          match self {              Self::Dump(scm) => Self::dump(scm),              Self::List => Self::list(), -            Self::Set(scm) => Self::set(scm), -            Self::Get(b64) => Self::get(b64), -            Self::Toggle(one, two) => Self::toggle(one, two), +            Self::Set(scm) => Self::set(console, scm), +            Self::Get(b64) => Self::get(console, b64), +            Self::Toggle(one, two) => Self::toggle(console, one, two),              Self::Fade(from, to, ms, hz, clear) => -                Self::fade(from, to, ms, hz, clear), +                Self::fade(console, from, to, ms, hz, clear),          }      }  } /* [impl Run for ColorJob] */ @@ -192,22 +203,22 @@ impl ColorJob          }      } -    fn set(scheme: Scheme) -> Result<()> +    fn set(con: Option<String>, scheme: Scheme) -> Result<()>      { -        let con = Console::current()?; -        vrb!("console fd: {}", con); +        let fd = open_console(con.as_deref())?; +        vrb!("console fd: {}", fd); -        con.apply_scheme(&scheme)?; -        con.clear()?; +        fd.apply_scheme(&scheme)?; +        fd.clear()?;          vrb!("successfully enabled scheme {:?}", scheme);          /* It’s fine to leak the fd, the kernel will clean up anyways. */          Ok(())      } -    fn get(b64: bool) -> Result<()> +    fn get(con: Option<String>, b64: bool) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          let scm = fd.current_scheme()?; @@ -224,15 +235,18 @@ impl ColorJob      /** Toggle between two schemes. Defaults to ``one`` in case neither scheme      is active.      */ -    fn toggle(one: Scheme, two: Scheme) -> Result<()> +    fn toggle(con: Option<String>, one: Scheme, two: Scheme) -> Result<()>      { -        let fd = Console::current()?; -        vrb!("console fd: {}", fd); +        let pal = { +            let fd = open_console(con.as_deref())?; +            vrb!("console fd: {}", fd); +            fd.current_palette()? +        }; -        if fd.current_palette()? == Palette::try_from(&one)? { -            Self::set(two) +        if pal == Palette::try_from(&one)? { +            Self::set(con, two)          } else { -            Self::set(one) +            Self::set(con, one)          }      } @@ -240,6 +254,7 @@ impl ColorJob      If ``from`` is ``None``, the current palette is used as starting point. */      fn fade( +        con: Option<String>,          from: Option<Scheme>,          to: Scheme,          dur: Duration, @@ -247,7 +262,7 @@ impl ColorJob          clear: bool,      ) -> Result<()>      { -        let fd = Console::current()?; +        let fd = open_console(con.as_deref())?;          vrb!("console fd: {}", fd);          let from = if let Some(from) = from { @@ -266,7 +281,7 @@ impl ColorJob  /** Subcommand and runtime parameters. */  #[derive(Debug)] -enum Job +enum Subcmd  {      /** Console palette ops. */      Colors(ColorJob), @@ -274,6 +289,9 @@ enum Job      Leds(LedJob),  } +#[derive(Debug)] +struct Job(Option<String>, Subcmd); +  impl<'a> Job  {      pub fn from_argv() -> Result<Job> @@ -292,6 +310,17 @@ impl<'a> Job                      .help("enable extra diagnostics")                      .takes_value(false),              ) +            .arg( +                Arg::with_name("console") +                    .set(ArgSettings::Global) +                    .short("C") +                    .long("console") +                    .help( +                        "path to the console device to operate on [default: \ +                         current console]", +                    ) +                    .takes_value(true), +            )              .subcommand(                  SubCommand::with_name("colors")                      .about("operations on the console palette") @@ -508,25 +537,37 @@ impl<'a> Job              VERBOSITY.store(true, Ordering::SeqCst);          } +        let con = matches.value_of("console").map(String::from); +          match matches.subcommand() {              ("colors", Some(subm)) =>                  match subm.subcommand() {                      ("dump", Some(subm)) => {                          if let Some(b64) = subm.value_of("base64") {                              let scheme = Scheme::from_base64(b64)?; -                            return Ok(Self::Colors(ColorJob::Dump(scheme))); +                            return Ok(Self( +                                con, +                                Subcmd::Colors(ColorJob::Dump(scheme)), +                            ));                          }                          if let Some(name) = subm.value_of("scheme") {                              let scm = Scheme::from(name); -                            return Ok(Self::Colors(ColorJob::Dump(scm))); +                            return Ok(Self( +                                con, +                                Subcmd::Colors(ColorJob::Dump(scm)), +                            ));                          }                          Err(anyhow!("dump requires an argument"))                      }, -                    ("list", _) => Ok(Self::Colors(ColorJob::List)), +                    ("list", _) => +                        Ok(Self(con, Subcmd::Colors(ColorJob::List))),                      ("set", Some(subm)) => {                          if let Some(b64) = subm.value_of("base64") {                              let scheme = Scheme::from_base64(&b64)?; -                            return Ok(Self::Colors(ColorJob::Set(scheme))); +                            return Ok(Self( +                                con, +                                Subcmd::Colors(ColorJob::Set(scheme)), +                            ));                          }                          let scheme = match subm.value_of("scheme") {                              Some("-") => Self::read_scheme_from_stdin(), @@ -547,20 +588,26 @@ impl<'a> Job                                      },                                  },                          }; -                        Ok(Self::Colors(ColorJob::Set(scheme))) +                        Ok(Self(con, Subcmd::Colors(ColorJob::Set(scheme))))                      },                      ("get", Some(subm)) => -                        Ok(Self::Colors(ColorJob::Get( -                            subm.is_present("base64"), -                        ))), +                        Ok(Self( +                            con, +                            Subcmd::Colors(ColorJob::Get( +                                subm.is_present("base64"), +                            )), +                        )),                      ("toggle", Some(subm)) => {                          match (subm.value_of("one"), subm.value_of("two")) {                              (Some(one), Some(two)) => {                                  vrb!("toggle schemes [{}] and [{}]", one, two); -                                Ok(Self::Colors(ColorJob::Toggle( -                                    Scheme::from(one), -                                    Scheme::from(two), -                                ))) +                                Ok(Self( +                                    con, +                                    Subcmd::Colors(ColorJob::Toggle( +                                        Scheme::from(one), +                                        Scheme::from(two), +                                    )), +                                ))                              },                              _ =>                                  Err(anyhow!( @@ -590,13 +637,16 @@ impl<'a> Job                                      "please supply color scheme to fade to"                                  )),                              (from, Some(to)) => -                                Ok(Self::Colors(ColorJob::Fade( -                                    from.map(Scheme::from), -                                    Scheme::from(to), -                                    dur, -                                    hz, -                                    clear, -                                ))), +                                Ok(Self( +                                    con, +                                    Subcmd::Colors(ColorJob::Fade( +                                        from.map(Scheme::from), +                                        Scheme::from(to), +                                        dur, +                                        hz, +                                        clear, +                                    )), +                                )),                          }                      },                      (junk, _) => @@ -612,21 +662,27 @@ impl<'a> Job                  match subm.subcommand() {                      ("get", Some(subm)) => {                          let raw = subm.is_present("u8"); -                        Ok(Self::Leds(LedJob::Get(raw))) +                        Ok(Self(con, Subcmd::Leds(LedJob::Get(raw))))                      },                      ("set", Some(subm)) => {                          if subm.is_present("revert") { -                            return Ok(Self::Leds(LedJob::Revert)); +                            return Ok(Self(con, Subcmd::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))); +                            return Ok(Self( +                                con, +                                Subcmd::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::Leds(LedJob::SetIndividual(cap, num, scr))) +                        Ok(Self( +                            con, +                            Subcmd::Leds(LedJob::SetIndividual(cap, num, scr)), +                        ))                      },                      (junk, _) =>                          Err(anyhow!( @@ -652,20 +708,18 @@ impl<'a> Job          vrb!("vtcol>");          Scheme::from_stdin()      } -} /* [impl Job] */ -impl Run for Job -{      fn run(self) -> Result<()>      { -        match self { -            Self::Colors(cols) => cols.run()?, -            Self::Leds(leds) => leds.run()?, +        let Job(con, cmd) = self; +        match cmd { +            Subcmd::Colors(cols) => cols.run(con)?, +            Subcmd::Leds(leds) => leds.run(con)?,          }          Ok(())      } -} /* [impl Run for Job] */ +} /* [impl Job] */  fn main() -> Result<()>  { | 
