diff options
author | Philipp Gesang <phg@phi-gamma.net> | 2021-12-12 21:52:11 +0100 |
---|---|---|
committer | Philipp Gesang <phg@phi-gamma.net> | 2021-12-12 21:52:14 +0100 |
commit | 55789cb1580c682a085e2ce57835f324665f18d1 (patch) | |
tree | 8a5f8d34cb12af6c5c8a2310c934de0e9334ffcd /src | |
parent | 18c8a22486819ab88e552b39eee8add0894afed9 (diff) | |
download | vtcol-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 154 |
1 files changed, 111 insertions, 43 deletions
@@ -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); |