summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs237
1 files changed, 207 insertions, 30 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 01f0187..aee486d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -46,7 +46,7 @@ fn cvt_r<T: IsMinusOne>(f: &mut dyn FnMut() -> T) -> io::Result<T>
/** Wrappers for ``ioctl_console(2)`` functionality. */
pub mod ioctl
{
- use super::{cvt_r, KbLedFlags, KbLedState, Palette};
+ use super::{cvt_r, KbLedFlags, KbLedState, KbLeds, Palette};
use libc::ioctl;
use std::{io::Result, os::unix::io::AsRawFd};
@@ -58,8 +58,11 @@ pub mod ioctl
pub const KB_101: libc::c_char = 0x0002;
pub const KDGETLED: libc::c_ulong = 0x4b31;
pub const KDSETLED: libc::c_ulong = 0x4b32;
+
pub const KDGKBLED: libc::c_ulong = 0x4B64;
pub const KDSKBLED: libc::c_ulong = 0x4B65;
+ pub const KD_KBLED_STATE_MASK: libc::c_ulong = 0x07;
+ pub const KD_KBLED_DEFAULT_MASK: libc::c_ulong = 0x70;
pub fn pio_cmap<F: AsRawFd>(fd: &F, pal: &Palette) -> Result<()>
{
@@ -113,7 +116,7 @@ pub mod ioctl
})
.map(|_| ())?;
- Ok(KbLedState::from(leds))
+ Ok(KbLedState(KbLeds::from(leds)))
}
/** If ``state`` is ``None`` it is taken to mean “revert to normal” as per
@@ -167,12 +170,13 @@ pub mod ioctl
})
.map(|_| ())?;
- Ok(KbLedFlags::from(flags))
+ KbLedFlags::try_from(flags as u8)
}
pub fn kdskbled<F: AsRawFd>(fd: &F, flags: KbLedFlags) -> Result<()>
{
- let flags = libc::c_ulong::from(flags);
+ let default = libc::c_ulong::from(flags.default);
+ let flags = libc::c_ulong::from(flags.flags) | (default << 4);
cvt_r(&mut || {
unsafe {
@@ -200,16 +204,12 @@ pub mod ioctl
}
}
-/** Base type which the LED state and flags are aliases of. */
#[derive(Clone, Copy, Debug)]
-pub struct KbLeds(u8);
-
-pub type KbLedFlags = KbLeds;
-pub type KbLedState = KbLeds;
+struct KbLeds(u8);
impl KbLeds
{
- pub fn new(cap: bool, num: bool, scr: bool) -> Self
+ fn new(cap: bool, num: bool, scr: bool) -> Self
{
let mut state = 0u8;
@@ -220,46 +220,33 @@ impl KbLeds
Self(state)
}
- #[inline]
- pub fn get(con: &Console) -> io::Result<Self> { ioctl::kdgetled(con) }
-
- #[inline]
- pub fn set(&self, con: &Console) -> io::Result<()>
- {
- ioctl::kdsetled(con, Some(*self))
- }
-
- #[inline]
- pub fn revert(con: &Console) -> io::Result<()>
- {
- ioctl::kdsetled(con, None)
- }
+ fn off() -> Self { Self(0) }
#[inline]
- pub fn cap(&self) -> bool { (self.0 & 0x4) != 0 }
+ fn cap(&self) -> bool { (self.0 & 0x4) != 0 }
#[inline]
- pub fn num(&self) -> bool { (self.0 & 0x2) != 0 }
+ fn num(&self) -> bool { (self.0 & 0x2) != 0 }
#[inline]
- pub fn scr(&self) -> bool { (self.0 & 0x1) != 0 }
+ fn scr(&self) -> bool { (self.0 & 0x1) != 0 }
#[inline]
- pub fn set_cap(&mut self, set: bool)
+ 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)
+ 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)
+ fn set_scr(&mut self, set: bool)
{
let bit = set as u8;
self.0 = (self.0 & !bit) | bit;
@@ -340,6 +327,196 @@ mod kb_led_state
}
}
+#[derive(Copy, Clone, Debug)]
+pub struct KbLedState(KbLeds);
+
+impl KbLedState
+{
+ pub fn new(cap: bool, num: bool, scr: bool) -> Self
+ {
+ Self(KbLeds::new(cap, num, scr))
+ }
+
+ #[inline]
+ pub fn get(con: &Console) -> io::Result<Self> { ioctl::kdgetled(con) }
+
+ #[inline]
+ pub fn set(&self, con: &Console) -> io::Result<()>
+ {
+ ioctl::kdsetled(con, Some(*self))
+ }
+
+ #[inline]
+ pub fn revert(con: &Console) -> io::Result<()>
+ {
+ ioctl::kdsetled(con, None)
+ }
+
+ #[inline]
+ pub fn cap(&self) -> bool { self.0.cap() }
+
+ #[inline]
+ pub fn num(&self) -> bool { self.0.num() }
+
+ #[inline]
+ pub fn scr(&self) -> bool { self.0.scr() }
+
+ #[inline]
+ pub fn set_cap(&mut self, set: bool) { self.0.set_cap(set) }
+
+ #[inline]
+ pub fn set_num(&mut self, set: bool) { self.0.set_num(set) }
+
+ #[inline]
+ pub fn set_scr(&mut self, set: bool) { self.0.set_scr(set) }
+}
+
+impl fmt::Display for KbLedState
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
+ {
+ write!(f, "{}", self.0)
+ }
+}
+
+impl From<libc::c_char> for KbLedState
+{
+ fn from(leds: libc::c_char) -> Self { Self(KbLeds(leds as u8)) }
+}
+
+impl From<KbLedState> for libc::c_ulong
+{
+ fn from(state: KbLedState) -> Self { state.0 .0 as libc::c_ulong }
+}
+
+impl From<KbLedState> for u8
+{
+ fn from(state: KbLedState) -> Self { state.0 .0 }
+}
+
+impl TryFrom<u8> for KbLedState
+{
+ type Error = io::Error;
+
+ fn try_from(val: u8) -> io::Result<Self>
+ {
+ Ok(Self(KbLeds::try_from(val)?))
+ }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct KbLedFlags
+{
+ flags: KbLeds,
+ default: KbLeds,
+}
+
+impl KbLedFlags
+{
+ pub fn new_flags(cap: bool, num: bool, scr: bool) -> Self
+ {
+ let flags = KbLeds::new(cap, num, scr);
+ let default = KbLeds::off();
+ Self { flags, default }
+ }
+
+ pub fn new(
+ fcap: bool,
+ fnum: bool,
+ fscr: bool,
+ dcap: bool,
+ dnum: bool,
+ dscr: bool,
+ ) -> Self
+ {
+ let flags = KbLeds::new(fcap, fnum, fscr);
+ let default = KbLeds::new(dcap, dnum, dscr);
+ Self { flags, default }
+ }
+
+ #[inline]
+ pub fn get(con: &Console) -> io::Result<Self> { ioctl::kdgkbled(con) }
+
+ #[inline]
+ pub fn set(&self, con: &Console) -> io::Result<()>
+ {
+ ioctl::kdskbled(con, *self)
+ }
+
+ #[inline]
+ pub fn cap(&self) -> bool { self.flags.cap() }
+
+ #[inline]
+ pub fn num(&self) -> bool { self.flags.num() }
+
+ #[inline]
+ pub fn scr(&self) -> bool { self.flags.scr() }
+
+ #[inline]
+ pub fn default_cap(&self) -> bool { self.default.cap() }
+
+ #[inline]
+ pub fn default_num(&self) -> bool { self.default.num() }
+
+ #[inline]
+ pub fn default_scr(&self) -> bool { self.default.scr() }
+
+ #[inline]
+ pub fn set_cap(&mut self, set: bool) { self.flags.set_cap(set) }
+
+ #[inline]
+ pub fn set_num(&mut self, set: bool) { self.flags.set_num(set) }
+
+ #[inline]
+ pub fn set_scr(&mut self, set: bool) { self.flags.set_scr(set) }
+
+ #[inline]
+ pub fn set_default_cap(&mut self, set: bool) { self.default.set_cap(set) }
+
+ #[inline]
+ pub fn set_default_num(&mut self, set: bool) { self.default.set_num(set) }
+
+ #[inline]
+ pub fn set_default_scr(&mut self, set: bool) { self.default.set_scr(set) }
+}
+
+impl From<KbLedFlags> for u8
+{
+ fn from(state: KbLedFlags) -> Self
+ {
+ state.flags.0 | (state.default.0 << 0x4)
+ }
+}
+
+impl TryFrom<u8> for KbLedFlags
+{
+ type Error = io::Error;
+
+ /** From the manpage:
+
+ The low order three bits (mask 0x7) get the current flag state,
+ and the low order bits of the next nibble (mask 0x70) get the
+ default flag state.
+ */
+ fn try_from(val: u8) -> io::Result<Self>
+ {
+ let flags = val & (ioctl::KD_KBLED_STATE_MASK as u8);
+ let default = val & (ioctl::KD_KBLED_DEFAULT_MASK as u8) >> 4;
+ let flags = KbLeds::try_from(flags)?;
+ let default = KbLeds::try_from(default)?;
+
+ Ok(Self { flags, default })
+ }
+}
+
+impl fmt::Display for KbLedFlags
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
+ {
+ write!(f, "[flags: {}; default: {}]", self.flags, self.default)
+ }
+}
+
#[derive(Debug)]
pub struct Fd(libc::c_int);