forked from Gnurou/v4l2r
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ioctl: add input/output selection/enumeration support
Showing
2 changed files
with
108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use std::ffi::c_int; | ||
use std::mem; | ||
use std::os::unix::io::AsRawFd; | ||
|
||
use nix::errno::Errno; | ||
use thiserror::Error; | ||
|
||
use crate::bindings::v4l2_input; | ||
use crate::bindings::v4l2_output; | ||
|
||
#[doc(hidden)] | ||
mod ioctl { | ||
use std::ffi::c_int; | ||
|
||
use crate::bindings::v4l2_input; | ||
use crate::bindings::v4l2_output; | ||
|
||
nix::ioctl_readwrite!(vidioc_enuminput, b'V', 26, v4l2_input); | ||
nix::ioctl_read!(vidioc_g_input, b'V', 38, c_int); | ||
nix::ioctl_readwrite!(vidioc_s_input, b'V', 39, c_int); | ||
|
||
nix::ioctl_read!(vidioc_g_output, b'V', 46, c_int); | ||
nix::ioctl_readwrite!(vidioc_s_output, b'V', 47, c_int); | ||
nix::ioctl_readwrite!(vidioc_enumoutput, b'V', 48, v4l2_output); | ||
} | ||
|
||
#[derive(Debug, Error)] | ||
pub enum SelectionError { | ||
#[error("selection {0} is out of range")] | ||
OutOfRange(usize), | ||
#[error("ioctl error: {0}")] | ||
IoctlError(Errno), | ||
} | ||
|
||
impl From<SelectionError> for Errno { | ||
fn from(err: SelectionError) -> Self { | ||
match err { | ||
SelectionError::OutOfRange(_) => Errno::EINVAL, | ||
SelectionError::IoctlError(e) => e, | ||
} | ||
} | ||
} | ||
|
||
pub fn enuminput<F: AsRawFd, R: From<v4l2_input>>( | ||
fd: &F, | ||
index: usize, | ||
) -> Result<R, SelectionError> { | ||
let mut input = v4l2_input { | ||
index: index as u32, | ||
..unsafe { mem::zeroed() } | ||
}; | ||
|
||
match unsafe { ioctl::vidioc_enuminput(fd.as_raw_fd(), &mut input) } { | ||
Ok(_) => Ok(R::from(input)), | ||
Err(Errno::EINVAL) => Err(SelectionError::OutOfRange(index)), | ||
Err(e) => Err(SelectionError::IoctlError(e)), | ||
} | ||
} | ||
|
||
pub fn g_input<F: AsRawFd>(fd: &F) -> Result<usize, Errno> { | ||
let mut input: c_int = 0; | ||
|
||
unsafe { ioctl::vidioc_g_input(fd.as_raw_fd(), &mut input) }.map(|r| r as usize) | ||
} | ||
|
||
pub fn s_input<F: AsRawFd>(fd: &F, index: usize) -> Result<(), SelectionError> { | ||
let mut input: c_int = index as c_int; | ||
|
||
match unsafe { ioctl::vidioc_s_input(fd.as_raw_fd(), &mut input) } { | ||
Ok(_) => Ok(()), | ||
Err(Errno::EINVAL) => Err(SelectionError::OutOfRange(index)), | ||
Err(e) => Err(SelectionError::IoctlError(e)), | ||
} | ||
} | ||
|
||
pub fn enumoutput<F: AsRawFd, R: From<v4l2_output>>( | ||
fd: &F, | ||
index: usize, | ||
) -> Result<R, SelectionError> { | ||
let mut output = v4l2_output { | ||
index: index as u32, | ||
..unsafe { mem::zeroed() } | ||
}; | ||
|
||
match unsafe { ioctl::vidioc_enumoutput(fd.as_raw_fd(), &mut output) } { | ||
Ok(_) => Ok(R::from(output)), | ||
Err(Errno::EINVAL) => Err(SelectionError::OutOfRange(index)), | ||
Err(e) => Err(SelectionError::IoctlError(e)), | ||
} | ||
} | ||
|
||
pub fn g_output<F: AsRawFd>(fd: &F) -> Result<usize, Errno> { | ||
let mut output: c_int = 0; | ||
|
||
unsafe { ioctl::vidioc_g_output(fd.as_raw_fd(), &mut output) }.map(|r| r as usize) | ||
} | ||
|
||
pub fn s_output<F: AsRawFd>(fd: &F, index: usize) -> Result<(), SelectionError> { | ||
let mut output: c_int = index as c_int; | ||
|
||
match unsafe { ioctl::vidioc_s_output(fd.as_raw_fd(), &mut output) } { | ||
Ok(_) => Ok(()), | ||
Err(Errno::EINVAL) => Err(SelectionError::OutOfRange(index)), | ||
Err(e) => Err(SelectionError::IoctlError(e)), | ||
} | ||
} |