summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2021-12-12 21:52:11 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2021-12-12 21:52:14 +0100
commit55789cb1580c682a085e2ce57835f324665f18d1 (patch)
tree8a5f8d34cb12af6c5c8a2310c934de0e9334ffcd
parent18c8a22486819ab88e552b39eee8add0894afed9 (diff)
downloadvtcol-55789cb1580c682a085e2ce57835f324665f18d1.tar.gz
lib: add ioctl wrappers for KDGKBLED / KDSKBLED
Reusing the same definitions as we have for KD{G,S}ETLED as they’re practically the same.
-rw-r--r--src/lib.rs154
1 files changed, 111 insertions, 43 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6a932d8..75595cd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -46,28 +46,20 @@ 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, KbLedState, Palette};
+ use super::{cvt_r, KbLedFlags, KbLedState, Palette};
use libc::ioctl;
use std::{io::Result, os::unix::io::AsRawFd};
/* XXX: can we get these into ``libc``? */
- pub const KDGKBTYPE: libc::c_ulong = 0x4b33; /* kd.h */
- pub const GIO_CMAP: libc::c_ulong = 0x00004B70; /* kd.h */
- pub const PIO_CMAP: libc::c_ulong = 0x00004B71; /* kd.h */
- pub const KB_101: libc::c_char = 0x0002; /* kd.h */
- pub const KDGETLED: libc::c_ulong = 0x4b31; /* kd.h */
- pub const KDSETLED: libc::c_ulong = 0x4b32; /* kd.h */
-
- pub fn kdgkbtype<F: AsRawFd>(fd: &F) -> Result<libc::c_char>
- {
- let mut kb: libc::c_char = 0;
-
- let _ = cvt_r(&mut || unsafe {
- ioctl(fd.as_raw_fd(), KDGKBTYPE, &mut kb as *mut _)
- })?;
-
- Ok(kb)
- }
+ /* kd.h */
+ pub const KDGKBTYPE: libc::c_ulong = 0x4b33;
+ pub const GIO_CMAP: libc::c_ulong = 0x00004B70;
+ pub const PIO_CMAP: libc::c_ulong = 0x00004B71;
+ 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 fn pio_cmap<F: AsRawFd>(fd: &F, pal: &Palette) -> Result<()>
{
@@ -133,14 +125,13 @@ pub mod ioctl
order bit is set, the LEDs revert to normal: displaying the state
of the keyboard functions of caps lock, num lock, and scroll lock.
*/
-
pub fn kdsetled<F: AsRawFd>(fd: &F, state: Option<KbLedState>)
-> Result<()>
{
- let leds: libc::c_char = if let Some(state) = state {
+ let leds: libc::c_ulong = if let Some(state) = state {
state.into()
} else {
- libc::c_char::MAX
+ libc::c_ulong::MAX
};
cvt_r(&mut || {
@@ -148,7 +139,7 @@ pub mod ioctl
ioctl(
fd.as_raw_fd(),
KDSETLED,
- std::mem::transmute::<&libc::c_char, *const libc::c_void>(
+ std::mem::transmute::<&libc::c_ulong, *const libc::c_void>(
&leds,
),
)
@@ -158,12 +149,65 @@ pub mod ioctl
Ok(())
}
+
+ pub fn kdgkbled<F: AsRawFd>(fd: &F) -> Result<KbLedFlags>
+ {
+ let mut flags: libc::c_char = 0;
+
+ cvt_r(&mut || {
+ unsafe {
+ ioctl(
+ fd.as_raw_fd(),
+ KDGKBLED,
+ std::mem::transmute::<&mut libc::c_char, *mut libc::c_void>(
+ &mut flags,
+ ),
+ )
+ }
+ })
+ .map(|_| ())?;
+
+ Ok(KbLedFlags::from(flags))
+ }
+
+ pub fn kdskbled<F: AsRawFd>(fd: &F, flags: KbLedFlags) -> Result<()>
+ {
+ let flags = libc::c_ulong::from(flags);
+
+ cvt_r(&mut || {
+ unsafe {
+ ioctl(
+ fd.as_raw_fd(),
+ KDSKBLED,
+ std::mem::transmute::<&libc::c_ulong, *const libc::c_void>(
+ &flags,
+ ),
+ )
+ }
+ })
+ .map(|_| ())
+ }
+
+ pub fn kdgkbtype<F: AsRawFd>(fd: &F) -> Result<libc::c_char>
+ {
+ let mut kb: libc::c_char = 0;
+
+ let _ = cvt_r(&mut || unsafe {
+ ioctl(fd.as_raw_fd(), KDGKBTYPE, &mut kb as *mut _)
+ })?;
+
+ Ok(kb)
+ }
}
+/** Base type which the LED state and flags are aliases of. */
#[derive(Clone, Copy, Debug)]
-pub struct KbLedState(u8);
+pub struct KbLeds(u8);
+
+pub type KbLedFlags = KbLeds;
+pub type KbLedState = KbLeds;
-impl KbLedState
+impl KbLeds
{
pub fn new(cap: bool, num: bool, scr: bool) -> Self
{
@@ -222,7 +266,7 @@ impl KbLedState
}
}
-impl fmt::Display for KbLedState
+impl fmt::Display for KbLeds
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
@@ -236,7 +280,7 @@ impl fmt::Display for KbLedState
}
}
-impl From<libc::c_char> for KbLedState
+impl From<libc::c_char> for KbLeds
{
fn from(leds: libc::c_char) -> Self
{
@@ -244,17 +288,17 @@ impl From<libc::c_char> for KbLedState
}
}
-impl From<KbLedState> for libc::c_char
+impl From<KbLeds> for libc::c_ulong
{
- fn from(state: KbLedState) -> Self { state.0 as libc::c_char }
+ fn from(state: KbLeds) -> Self { state.0 as libc::c_ulong }
}
-impl From<KbLedState> for u8
+impl From<KbLeds> for u8
{
- fn from(state: KbLedState) -> Self { state.0 }
+ fn from(state: KbLeds) -> Self { state.0 }
}
-impl TryFrom<u8> for KbLedState
+impl TryFrom<u8> for KbLeds
{
type Error = io::Error;
@@ -277,25 +321,49 @@ impl TryFrom<u8> for KbLedState
#[cfg(test)]
mod kb_led_state
{
- use super::KbLedState;
+ use super::KbLeds;
#[test]
fn create()
{
- assert_eq!(0u8, KbLedState::new(false, false, false).into());
- assert_eq!(1u8, KbLedState::new(false, false, true).into());
- assert_eq!(2u8, KbLedState::new(false, true, false).into());
- assert_eq!(4u8, KbLedState::new(true, false, false).into());
- assert_eq!(6u8, KbLedState::new(true, true, false).into());
-
- assert_eq!(0u8, KbLedState::from(0u8 as libc::c_char).into());
- assert_eq!(1u8, KbLedState::from(1u8 as libc::c_char).into());
- assert_eq!(2u8, KbLedState::from(2u8 as libc::c_char).into());
- assert_eq!(4u8, KbLedState::from(4u8 as libc::c_char).into());
- assert_eq!(6u8, KbLedState::from(6u8 as libc::c_char).into());
+ assert_eq!(0u8, KbLeds::new(false, false, false).into());
+ assert_eq!(1u8, KbLeds::new(false, false, true).into());
+ assert_eq!(2u8, KbLeds::new(false, true, false).into());
+ assert_eq!(4u8, KbLeds::new(true, false, false).into());
+ assert_eq!(6u8, KbLeds::new(true, true, false).into());
+
+ assert_eq!(0u8, KbLeds::from(0u8 as libc::c_char).into());
+ assert_eq!(1u8, KbLeds::from(1u8 as libc::c_char).into());
+ assert_eq!(2u8, KbLeds::from(2u8 as libc::c_char).into());
+ assert_eq!(4u8, KbLeds::from(4u8 as libc::c_char).into());
+ assert_eq!(6u8, KbLeds::from(6u8 as libc::c_char).into());
}
}
+//#[derive(Clone, Copy, Debug)]
+//pub struct KbLedFlags(u8);
+
+//impl KbLedFlags {
+//pub fn new(cap: bool, num: bool, scr: bool) -> Self
+//{
+//let mut flags = 0u8;
+
+//flags |= (cap as u8) << 2;
+//flags |= (num as u8) << 1;
+//flags |= scr as u8;
+
+//Self(flags)
+//}
+//}
+
+//impl From<libc::c_char> for KbLedFlags
+//{
+//fn from(flags: libc::c_char) -> Self
+//{
+//Self::new(flags & 0x4 != 0, flags & 0x2 != 0, flags & 0x1 != 0)
+//}
+//}
+
#[derive(Debug)]
pub struct Fd(libc::c_int);