Improve detect error handling
This commit is contained in:
		
							parent
							
								
									2f04f174b7
								
							
						
					
					
						commit
						bee2001e28
					
				| 
						 | 
				
			
			@ -8,14 +8,14 @@ build="build.rs"
 | 
			
		|||
[dependencies]
 | 
			
		||||
log = "0.4.14"
 | 
			
		||||
lazycell = "1.3.0"
 | 
			
		||||
anyhow = "1.0.38"
 | 
			
		||||
thiserror = "1.0.23"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(windows)'.dependencies]
 | 
			
		||||
widestring = "0.4.3"
 | 
			
		||||
 | 
			
		||||
[target.'cfg(target_os="linux")'.dependencies]
 | 
			
		||||
libc = "0.2.85"
 | 
			
		||||
anyhow = "1.0.38"
 | 
			
		||||
thiserror = "1.0.23"
 | 
			
		||||
scopeguard = "1.1.0"
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,8 @@ use libc::{
 | 
			
		|||
  __errno_location, close, epoll_ctl, epoll_event, epoll_wait, EINTR, EPOLLIN, EPOLL_CTL_ADD,
 | 
			
		||||
};
 | 
			
		||||
use log::{error, trace};
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
use crate::event::Status::*;
 | 
			
		||||
use crate::event::Variant::*;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +61,7 @@ impl EVDEVSource {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn initialize(&mut self) {
 | 
			
		||||
  pub fn initialize(&mut self) -> Result<()> {
 | 
			
		||||
    let context = Context::new().expect("unable to obtain xkb context");
 | 
			
		||||
    let keymap = Keymap::new(&context).expect("unable to create xkb keymap");
 | 
			
		||||
    match get_devices(&keymap) {
 | 
			
		||||
| 
						 | 
				
			
			@ -71,11 +73,14 @@ impl EVDEVSource {
 | 
			
		|||
            error!(
 | 
			
		||||
              "You can either add the current user to the 'input' group or run espanso as root"
 | 
			
		||||
            );
 | 
			
		||||
            return Err(EVDEVSourceError::PermissionDenied().into())
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        panic!("error when initilizing EVDEV source {}", error);
 | 
			
		||||
        return Err(error)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn eventloop(&self, event_callback: EVDEVSourceCallback) {
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +148,12 @@ impl EVDEVSource {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Error, Debug)]
 | 
			
		||||
pub enum EVDEVSourceError {
 | 
			
		||||
  #[error("permission denied")]
 | 
			
		||||
  PermissionDenied(),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<RawInputEvent> for Option<InputEvent> {
 | 
			
		||||
  fn from(raw: RawInputEvent) -> Option<InputEvent> {
 | 
			
		||||
    match raw {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,9 @@ use lazycell::LazyCell;
 | 
			
		|||
use log::{error, trace, warn};
 | 
			
		||||
use widestring::U16CStr;
 | 
			
		||||
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
use crate::event::Status::*;
 | 
			
		||||
use crate::event::Variant::*;
 | 
			
		||||
use crate::event::{InputEvent, Key, KeyboardEvent, Variant};
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +65,7 @@ pub struct RawInputEvent {
 | 
			
		|||
#[allow(improper_ctypes)]
 | 
			
		||||
#[link(name = "espansodetect", kind = "static")]
 | 
			
		||||
extern "C" {
 | 
			
		||||
  pub fn detect_initialize(_self: *const Win32Source) -> *mut c_void;
 | 
			
		||||
  pub fn detect_initialize(_self: *const Win32Source, error_code: *mut i32) -> *mut c_void;
 | 
			
		||||
 | 
			
		||||
  pub fn detect_eventloop(
 | 
			
		||||
    window: *const c_void,
 | 
			
		||||
| 
						 | 
				
			
			@ -87,14 +90,22 @@ impl Win32Source {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn initialize(&mut self) {
 | 
			
		||||
    let handle = unsafe { detect_initialize(self as *const Win32Source) };
 | 
			
		||||
  pub fn initialize(&mut self) -> Result<()> {
 | 
			
		||||
    let mut error_code = 0;
 | 
			
		||||
    let handle = unsafe { detect_initialize(self as *const Win32Source, &mut error_code) };
 | 
			
		||||
 | 
			
		||||
    if handle.is_null() {
 | 
			
		||||
      panic!("Unable to initialize Win32Source");
 | 
			
		||||
      let error = match error_code {
 | 
			
		||||
        -1 => Win32SourceError::WindowFailed(),
 | 
			
		||||
        -2 => Win32SourceError::RawInputFailed(),
 | 
			
		||||
        _ => Win32SourceError::Unknown(),
 | 
			
		||||
      };
 | 
			
		||||
      return Err(error.into())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    self.handle = handle;
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn eventloop(&self, event_callback: Win32SourceCallback) {
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +151,18 @@ impl Drop for Win32Source {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Error, Debug)]
 | 
			
		||||
pub enum Win32SourceError {
 | 
			
		||||
  #[error("window registration failed")]
 | 
			
		||||
  WindowFailed(),
 | 
			
		||||
 | 
			
		||||
  #[error("raw input API failed")]
 | 
			
		||||
  RawInputFailed(),
 | 
			
		||||
 | 
			
		||||
  #[error("unknown error")]
 | 
			
		||||
  Unknown(),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<RawInputEvent> for Option<InputEvent> {
 | 
			
		||||
  fn from(raw: RawInputEvent) -> Option<InputEvent> {
 | 
			
		||||
    let status = match raw.status {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -246,7 +246,7 @@ LRESULT CALLBACK detect_window_procedure(HWND window, unsigned int msg, WPARAM w
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void * detect_initialize(void *_self)
 | 
			
		||||
void * detect_initialize(void *_self, int32_t *error_code)
 | 
			
		||||
{
 | 
			
		||||
  HWND window = NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -308,12 +308,14 @@ void * detect_initialize(void *_self)
 | 
			
		|||
 | 
			
		||||
    if (RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE)
 | 
			
		||||
    { // Something went wrong, error.
 | 
			
		||||
      *error_code = -2;
 | 
			
		||||
      return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // Something went wrong, error.
 | 
			
		||||
    *error_code = -1;
 | 
			
		||||
    return nullptr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ typedef void (*EventCallback)(void * rust_istance, InputEvent data);
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
// Initialize the Raw Input API and the Window.
 | 
			
		||||
extern "C" void * detect_initialize(void * rust_istance);
 | 
			
		||||
extern "C" void * detect_initialize(void * rust_istance, int32_t *error_code);
 | 
			
		||||
 | 
			
		||||
// Run the event loop. Blocking call.
 | 
			
		||||
extern "C" int32_t detect_eventloop(void * window, EventCallback callback);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,9 @@ use std::{
 | 
			
		|||
use lazycell::LazyCell;
 | 
			
		||||
use log::{error, trace, warn};
 | 
			
		||||
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
use crate::event::Status::*;
 | 
			
		||||
use crate::event::Variant::*;
 | 
			
		||||
use crate::event::{InputEvent, Key, KeyboardEvent, Variant};
 | 
			
		||||
| 
						 | 
				
			
			@ -88,23 +91,26 @@ impl X11Source {
 | 
			
		|||
    unsafe { detect_check_x11() != 0 }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn initialize(&mut self) {
 | 
			
		||||
  pub fn initialize(&mut self) -> Result<()> {
 | 
			
		||||
    let mut error_code = 0;
 | 
			
		||||
    let handle = unsafe { detect_initialize(self as *const X11Source, &mut error_code) };
 | 
			
		||||
 | 
			
		||||
    if handle.is_null() {
 | 
			
		||||
      match error_code {
 | 
			
		||||
        -1 => panic!("Unable to initialize X11Source, cannot open displays"),
 | 
			
		||||
        -2 => panic!("Unable to initialize X11Source, X Record Extension is not installed"),
 | 
			
		||||
        -3 => panic!("Unable to initialize X11Source, X Keyboard Extension is not installed"),
 | 
			
		||||
        -4 => panic!("Unable to initialize X11Source, cannot initialize record range"),
 | 
			
		||||
        -5 => panic!("Unable to initialize X11Source, cannot initialize XRecord context"),
 | 
			
		||||
        -6 => panic!("Unable to initialize X11Source, cannot enable XRecord context"),
 | 
			
		||||
        _ => panic!("Unable to initialize X11Source, unknown error"),
 | 
			
		||||
      }
 | 
			
		||||
      let error = match error_code {
 | 
			
		||||
        -1 => X11SourceError::DisplayFailure(),
 | 
			
		||||
        -2 => X11SourceError::XRecordMissing(),
 | 
			
		||||
        -3 => X11SourceError::XKeyboardMissing(),
 | 
			
		||||
        -4 => X11SourceError::FailedRegistration("cannot initialize record range".to_owned()),
 | 
			
		||||
        -5 => X11SourceError::FailedRegistration("cannot initialize XRecord context".to_owned()),
 | 
			
		||||
        -6 => X11SourceError::FailedRegistration("cannot enable XRecord context".to_owned()),
 | 
			
		||||
        _ => X11SourceError::Unknown(),
 | 
			
		||||
      };
 | 
			
		||||
      return Err(error.into())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    self.handle = handle;
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn eventloop(&self, event_callback: X11SourceCallback) {
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +156,24 @@ impl Drop for X11Source {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Error, Debug)]
 | 
			
		||||
pub enum X11SourceError {
 | 
			
		||||
  #[error("cannot open displays")]
 | 
			
		||||
  DisplayFailure(),
 | 
			
		||||
 | 
			
		||||
  #[error("X Record Extension is not installed")]
 | 
			
		||||
  XRecordMissing(),
 | 
			
		||||
 | 
			
		||||
  #[error("X Keyboard Extension is not installed")]
 | 
			
		||||
  XKeyboardMissing(),
 | 
			
		||||
 | 
			
		||||
  #[error("failed registration: ${0}")]
 | 
			
		||||
  FailedRegistration(String),
 | 
			
		||||
 | 
			
		||||
  #[error("unknown error")]
 | 
			
		||||
  Unknown(),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<RawInputEvent> for Option<InputEvent> {
 | 
			
		||||
  fn from(raw: RawInputEvent) -> Option<InputEvent> {
 | 
			
		||||
    let status = match raw.status {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user