/* * This file is part of espanso. * * Copyright (C) 2019-2021 Federico Terzi * * espanso is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * espanso is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with espanso. If not, see . */ use crate::Injector; use anyhow::{bail, ensure, Result}; use log::{error, warn}; mod default; mod ffi; mod xdotool; pub struct X11ProxyInjector { default_injector: Option, xdotool_injector: Option, } impl X11ProxyInjector { pub fn new() -> Result { let default_injector = match default::X11DefaultInjector::new() { Ok(injector) => Some(injector), Err(err) => { error!("X11DefaultInjector could not be initialized: {:?}", err); warn!("falling back to xdotool injector"); None } }; let xdotool_injector = match xdotool::X11XDOToolInjector::new() { Ok(injector) => Some(injector), Err(err) => { error!("X11XDOToolInjector could not be initialized: {:?}", err); None } }; if default_injector.is_none() && xdotool_injector.is_none() { bail!("unable to initialize injectors, neither the default or xdotool fallback could be initialized"); } Ok(X11ProxyInjector { default_injector, xdotool_injector, }) } fn get_active_injector(&self, options: &crate::InjectionOptions) -> Result<&dyn Injector> { ensure!( self.default_injector.is_some() || self.xdotool_injector.is_some(), "unable to get active injector, neither default or xdotool fallback are available." ); if options.x11_use_xdotool_fallback { if let Some(xdotool_injector) = self.xdotool_injector.as_ref() { return Ok(xdotool_injector); } else if let Some(default_injector) = self.default_injector.as_ref() { return Ok(default_injector); } } else if let Some(default_injector) = self.default_injector.as_ref() { return Ok(default_injector); } else if let Some(xdotool_injector) = self.xdotool_injector.as_ref() { return Ok(xdotool_injector); } unreachable!() } } impl Injector for X11ProxyInjector { fn send_string(&self, string: &str, options: crate::InjectionOptions) -> Result<()> { self .get_active_injector(&options)? .send_string(string, options) } fn send_keys(&self, keys: &[crate::keys::Key], options: crate::InjectionOptions) -> Result<()> { self.get_active_injector(&options)?.send_keys(keys, options) } fn send_key_combination( &self, keys: &[crate::keys::Key], options: crate::InjectionOptions, ) -> Result<()> { self .get_active_injector(&options)? .send_key_combination(keys, options) } }