summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-11-10 23:01:38 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-11-10 23:12:18 +0100
commit3925f2c7f5927c07a5db305eaed9087631d85b0d (patch)
treedbc57f26c9f7708d839921b68f92345c8a6b8994
parentb9797074f5780d2640539db26142fcc79bada3b1 (diff)
downloadvtcol-3925f2c7f5927c07a5db305eaed9087631d85b0d.tar.gz
implement subcommand get (GIO_CMAP)
Get the currently active color palette using ioctl(GIO_CMAP) and attempt to match it against the builtin schemes.
-rw-r--r--src/vtcol.rs125
1 files changed, 89 insertions, 36 deletions
diff --git a/src/vtcol.rs b/src/vtcol.rs
index a007185..17f0489 100644
--- a/src/vtcol.rs
+++ b/src/vtcol.rs
@@ -109,6 +109,7 @@ enum Scheme
Default,
SolarizedDark,
SolarizedLight,
+ Palette(Palette),
Custom(Option<PathBuf>),
}
@@ -117,11 +118,12 @@ impl<'a> fmt::Display for Scheme
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
match self {
- Scheme::Default => write!(f, "default"),
- Scheme::SolarizedDark => write!(f, "solarized_dark"),
- Scheme::SolarizedLight => write!(f, "solarized_light"),
- Scheme::Custom(None) => write!(f, "<read stdin>"),
- Scheme::Custom(Some(fname)) => write!(f, "{}", fname.display()),
+ Self::Default => write!(f, "default"),
+ Self::SolarizedDark => write!(f, "solarized_dark"),
+ Self::SolarizedLight => write!(f, "solarized_light"),
+ Self::Custom(None) => write!(f, "<read stdin>"),
+ Self::Custom(Some(fname)) => write!(f, "{}", fname.display()),
+ Self::Palette(pal) => write!(f, "palette: {}", pal),
}
}
} /* [impl fmt::String for Scheme] */
@@ -151,6 +153,25 @@ impl From<&str> for Scheme
}
}
+/** Try to match the palette against one of the predefined schemes. */
+impl From<Palette> for Scheme
+{
+ fn from(pal: Palette) -> Scheme
+ {
+ if pal == Palette::from(&DEFAULT_COLORS) {
+ return Self::Default;
+ }
+ if pal == Palette::from(&SOLARIZED_COLORS_DARK) {
+ return Self::SolarizedDark;
+ }
+ if pal == Palette::from(&SOLARIZED_COLORS_LIGHT) {
+ return Self::SolarizedLight;
+ }
+
+ Self::Palette(pal)
+ }
+}
+
/* struct Job -- Runtime parameters.
*/
#[derive(Debug)]
@@ -160,8 +181,10 @@ enum Job
List,
/** Dump a scheme. */
Dump(Scheme),
- /** The color scheme to switch to. */
+ /** Switch to color scheme. */
Set(Scheme),
+ /** Get currently active scheme. */
+ Get,
}
impl<'a> Job
@@ -205,6 +228,9 @@ impl<'a> Job
.takes_value(true),
),
)
+ .subcommand(
+ SubCommand::with_name("get").about("get current color scheme"),
+ )
.arg(
Arg::with_name("verbose")
.short("v")
@@ -249,6 +275,7 @@ impl<'a> Job
};
Ok(Self::Set(scheme))
},
+ ("get", _) => Ok(Self::Get),
(junk, _) =>
Err(anyhow!(
"invalid subcommand [{}]; try “{} --help”",
@@ -277,6 +304,7 @@ impl<'a> Job
Scheme::Custom(None) => Self::dump_palette(Palette::from_stdin()),
Scheme::Custom(Some(fname)) =>
Self::dump_palette(Palette::from_file(&fname)),
+ Scheme::Palette(pal) => Self::dump_palette(pal),
}
}
@@ -294,6 +322,7 @@ impl<'a> Job
Self::Dump(scm) => Self::dump(scm),
Self::List => Self::schemes(),
Self::Set(scm) => Self::set_scheme(scm)?,
+ Self::Get => Self::get_scheme()?,
}
Ok(())
@@ -301,17 +330,11 @@ impl<'a> Job
fn set_scheme(scheme: Scheme) -> Result<()>
{
- let pal: Palette = match scheme {
- Scheme::Default => Palette::from(&DEFAULT_COLORS),
- Scheme::SolarizedDark => Palette::from(&SOLARIZED_COLORS_DARK),
- Scheme::SolarizedLight => Palette::from(&SOLARIZED_COLORS_LIGHT),
- Scheme::Custom(None) => Palette::from_stdin(),
- Scheme::Custom(Some(ref fname)) => Palette::from_file(fname),
- };
+ let pal = Palette::from(&scheme);
vrb!("Using palette:");
vrb!("{}", pal);
let fd = get_console_fd()?;
- vrb!("fd: {}", fd);
+ vrb!("console fd: {}", fd);
ioctl_pio_cmap(fd, &pal)?;
@@ -320,6 +343,20 @@ impl<'a> Job
/* It’s fine to leak the fd, the kernel will clean up anyways. */
Ok(())
}
+
+ fn get_scheme() -> Result<()>
+ {
+ let fd = get_console_fd()?;
+ vrb!("console fd: {}", fd);
+
+ let pal = ioctl_gio_cmap(fd)?;
+ let scm = Scheme::from(pal);
+
+ vrb!("active scheme:");
+ println!("{}", scm);
+
+ Ok(())
+ }
} /* [impl Job] */
/* Rust appears to come with two wrappers for ``ioctl(2)``, but neither can be utilized for our
@@ -393,6 +430,7 @@ fn rgb_of_hex_triplet(def: &str) -> (u8, u8, u8)
(r, g, b)
}
+#[derive(Eq, PartialEq, Clone)]
pub struct Palette([u8; PALETTE_BYTES]);
impl Palette
@@ -400,28 +438,6 @@ impl Palette
/** Construct an all-zero ``Palette``. */
pub fn new() -> Self { Self([0u8; PALETTE_BYTES]) }
- /* [Palette::new] */
-
- /** Obtain a ``Palette`` from a ``RawPalette``. */
- pub fn from(colors: &RawPalette) -> Self
- {
- let mut idx: usize = 0;
- let mut pal: [u8; PALETTE_BYTES] = [0; PALETTE_BYTES];
-
- for def in colors.iter() {
- let (r, g, b) = rgb_of_hex_triplet(*def);
- pal[idx] = r;
- pal[idx + 1] = g;
- pal[idx + 2] = b;
- //println!(">> {} -> {:X} {:X} {:X}", def, r, g, b);
- idx += 3;
- }
-
- Self(pal)
- }
-
- /* [Palette::from] */
-
pub fn dummy() -> Self { Self::from(&DUMMY_COLORS) }
pub fn from_buffered_reader(reader: &mut dyn std::io::BufRead) -> Self
@@ -555,6 +571,43 @@ impl fmt::Debug for Palette
}
} /* [impl fmt::Debug for Palette] */
+/** Obtain a ``Palette`` from a ``Scheme``. */
+impl From<&Scheme> for Palette
+{
+ fn from(scm: &Scheme) -> Self
+ {
+ match scm {
+ Scheme::Default => Self::from(&DEFAULT_COLORS),
+ Scheme::SolarizedDark => Self::from(&SOLARIZED_COLORS_DARK),
+ Scheme::SolarizedLight => Self::from(&SOLARIZED_COLORS_LIGHT),
+ Scheme::Custom(None) => Self::from_stdin(),
+ Scheme::Custom(Some(ref fname)) => Self::from_file(fname),
+ Scheme::Palette(pal) => pal.clone(),
+ }
+ }
+}
+
+/** Obtain a ``Palette`` from a ``RawPalette``. */
+impl From<&RawPalette<'_>> for Palette
+{
+ fn from(colors: &RawPalette<'_>) -> Self
+ {
+ let mut idx: usize = 0;
+ let mut pal: [u8; PALETTE_BYTES] = [0; PALETTE_BYTES];
+
+ for def in colors.iter() {
+ let (r, g, b) = rgb_of_hex_triplet(*def);
+ pal[idx] = r;
+ pal[idx + 1] = g;
+ pal[idx + 2] = b;
+ //println!(">> {} -> {:X} {:X} {:X}", def, r, g, b);
+ idx += 3;
+ }
+
+ Self(pal)
+ }
+}
+
fn fd_of_path(path: &std::path::Path) -> Option<Fd>
{
let p = std::ffi::CString::new(path.to_str().unwrap()).unwrap();