From 62ee11ec1924de50c4ed262ac0f7e3021cb595e5 Mon Sep 17 00:00:00 2001 From: Magnus Ulimoen Date: Fri, 24 Jul 2020 00:49:06 +0200 Subject: [PATCH] descriptor --- src/main.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2c367ac..ec128ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,7 @@ impl Context { Ok((Context {}, Version(version_code))) } - fn devices(&self, only_local: bool) -> Result, Error> { + fn devices(&self, only_local: bool) -> Result, Error> { let mut device_list: *mut *const SANE_Device = std::ptr::null_mut(); unsafe { checked(|| sane_get_devices(&mut device_list, only_local as _))?; @@ -65,7 +65,6 @@ impl Context { num_devices += 1; } } - println!("{}", num_devices); Ok((0..num_devices).map(move |i| { let device = unsafe { *device_list.offset(i) }; @@ -73,6 +72,11 @@ impl Context { })) } } +impl Drop for Context { + fn drop(&mut self) { + unsafe { sane_exit() } + } +} struct Device(*const SANE_Device); @@ -93,11 +97,65 @@ impl Device { let cstr = unsafe { CStr::from_ptr((*self.0).type_) }; cstr.to_str().unwrap() } + fn open(&self) -> Result { + let mut handle = std::ptr::null_mut(); + unsafe { checked(|| sane_open((*self.0).name, &mut handle))? }; + + Ok(Handle(handle)) + } } -impl Drop for Context { +struct Handle(SANE_Handle); + +impl Drop for Handle { fn drop(&mut self) { - unsafe { sane_exit() } + unsafe { sane_close(self.0) } + } +} + +impl Handle { + fn descriptors(&self) -> impl ExactSizeIterator + '_ { + // Guaranteed to exist + let first_desc = self.get_descriptor(0).unwrap(); + assert_eq!(first_desc.type_(), SANE_Value_Type_SANE_TYPE_INT); + assert_eq!(first_desc.size(), std::mem::size_of::() as _); + let mut num_desc: SANE_Int = 0; + unsafe { + checked(|| { + sane_control_option( + self.0, + 0, + SANE_Action_SANE_ACTION_GET_VALUE, + &mut num_desc as *mut _ as _, + std::ptr::null_mut(), + ) + }) + .unwrap() + }; + (0..num_desc).map(move |i| self.get_descriptor(i as _).unwrap()) + } + fn get_descriptor(&self, index: usize) -> Option { + let desc = unsafe { sane_get_option_descriptor(self.0, index as _) }; + if desc.is_null() { + None + } else { + Some(Descriptor(desc)) + } + } +} + +struct Descriptor(*const SANE_Option_Descriptor); + +impl Descriptor { + fn name(&self) -> &str { + let cstr = unsafe { CStr::from_ptr((*self.0).name) }; + cstr.to_str().unwrap() + } + fn type_(&self) -> SANE_Value_Type { + unsafe { (*self.0).type_ } + } + fn size(&self) -> SANE_Int { + unsafe { (*self.0).size } } } @@ -125,11 +183,22 @@ fn main() { version.minor(), version.build() ); + let mut chosen_device = None; for device in context.devices(true).unwrap() { println!("Device:"); - println!("\tname: {}", device.name()); + let name = device.name(); + println!("\tname: {}", name); println!("\tvendor: {}", device.vendor()); println!("\tmodel: {}", device.model()); println!("\ttype: {}", device.type_()); + chosen_device = Some(device); + } + + let device = chosen_device.unwrap(); + let handle = device.open().unwrap(); + + println!("Options:"); + for descriptor in handle.descriptors() { + println!("\t{}", descriptor.name()); } }