Improve detect error handling

This commit is contained in:
Federico Terzi 2021-02-08 17:16:35 +01:00
parent 2f04f174b7
commit bee2001e28
6 changed files with 80 additions and 20 deletions

View File

@ -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]

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);

View File

@ -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 {