From 32b1de8ddc60a96c4ca4f0ebee85870381860732 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Tue, 16 Mar 2021 12:30:18 +0100 Subject: [PATCH] feat(clipboard): define base library interface --- Cargo.lock | 17 ++++++++ Cargo.toml | 1 + espanso-clipboard/Cargo.toml | 29 +++++++++++++ espanso-clipboard/build.rs | 81 +++++++++++++++++++++++++++++++++++ espanso-clipboard/src/lib.rs | 82 ++++++++++++++++++++++++++++++++++++ espanso/Cargo.toml | 1 + espanso/src/main.rs | 15 +++++-- 7 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 espanso-clipboard/Cargo.toml create mode 100644 espanso-clipboard/build.rs create mode 100644 espanso-clipboard/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d061d3d..84bc161 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,7 @@ dependencies = [ name = "espanso" version = "1.0.0" dependencies = [ + "espanso-clipboard", "espanso-config", "espanso-detect", "espanso-inject", @@ -233,6 +234,22 @@ dependencies = [ "simplelog", ] +[[package]] +name = "espanso-clipboard" +version = "0.1.0" +dependencies = [ + "anyhow", + "cc", + "itertools", + "lazy_static", + "lazycell", + "libc", + "log", + "scopeguard", + "thiserror", + "widestring", +] + [[package]] name = "espanso-config" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 54849d5..56b579a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ members = [ "espanso-ipc", "espanso-config", "espanso-match", + "espanso-clipboard", ] \ No newline at end of file diff --git a/espanso-clipboard/Cargo.toml b/espanso-clipboard/Cargo.toml new file mode 100644 index 0000000..f364a3f --- /dev/null +++ b/espanso-clipboard/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "espanso-clipboard" +version = "0.1.0" +authors = ["Federico Terzi "] +edition = "2018" +build="build.rs" + +[features] +# If the wayland feature is enabled, all X11 dependencies will be dropped +# and only EVDEV-based methods will be supported. +wayland = [] + +[dependencies] +log = "0.4.14" +lazycell = "1.3.0" +anyhow = "1.0.38" +thiserror = "1.0.23" +lazy_static = "1.4.0" + +[target.'cfg(windows)'.dependencies] +widestring = "0.4.3" + +[target.'cfg(target_os="linux")'.dependencies] +libc = "0.2.85" +scopeguard = "1.1.0" +itertools = "0.10.0" + +[build-dependencies] +cc = "1.0.66" \ No newline at end of file diff --git a/espanso-clipboard/build.rs b/espanso-clipboard/build.rs new file mode 100644 index 0000000..4a23b65 --- /dev/null +++ b/espanso-clipboard/build.rs @@ -0,0 +1,81 @@ +/* + * 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 . + */ + +#[cfg(target_os = "windows")] +fn cc_config() { + println!("cargo:rerun-if-changed=src/win32/native.cpp"); + println!("cargo:rerun-if-changed=src/win32/native.h"); + cc::Build::new() + .cpp(true) + .include("src/win32/native.h") + .file("src/win32/native.cpp") + .compile("espansoclipboard"); + + println!("cargo:rustc-link-lib=static=espansoclipboard"); + println!("cargo:rustc-link-lib=dylib=user32"); + #[cfg(target_env = "gnu")] + println!("cargo:rustc-link-lib=dylib=stdc++"); +} + +#[cfg(target_os = "linux")] +fn cc_config() { + if cfg!(not(feature = "wayland")) { + println!("cargo:rerun-if-changed=src/x11/native/native.h"); + println!("cargo:rerun-if-changed=src/x11/native/native.c"); + cc::Build::new() + .cpp(true) + .include("src/x11/native/clip/clip.h") + .include("src/x11/native/clip/clip_common.h") + .include("src/x11/native/clip/clip_lock_impl.h") + .include("src/x11/native/clip/clip_x11_png.h") + .include("src/x11/native/native.h") + .file("src/x11/native/clip/clip.cpp") + .file("src/x11/native/clip/clip_x11.cpp") + .file("src/x11/native/clip/image.cpp") + .file("src/x11/native/native.cpp") + .define("CLIP_X11_WITH_PNG", None) + .compile("espansoclipboardx11"); + + println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu/"); + println!("cargo:rustc-link-lib=static=espansoclipboardx11"); + + // TODO: link xcb, libpng? + + println!("cargo:rustc-link-lib=dylib=xcb"); + //println!("cargo:rustc-link-lib=dylib=X11"); + } +} + +#[cfg(target_os = "macos")] +fn cc_config() { + println!("cargo:rerun-if-changed=src/mac/native.mm"); + println!("cargo:rerun-if-changed=src/mac/native.h"); + cc::Build::new() + .cpp(true) + .include("src/mac/native.h") + .file("src/mac/native.mm") + .compile("espansoclipboard"); + println!("cargo:rustc-link-lib=dylib=c++"); + println!("cargo:rustc-link-lib=static=espansoclipboard"); + println!("cargo:rustc-link-lib=framework=Cocoa"); +} + +fn main() { + cc_config(); +} diff --git a/espanso-clipboard/src/lib.rs b/espanso-clipboard/src/lib.rs new file mode 100644 index 0000000..99af568 --- /dev/null +++ b/espanso-clipboard/src/lib.rs @@ -0,0 +1,82 @@ +/* + * 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 std::path::Path; + +use anyhow::Result; +use log::info; + +#[cfg(target_os = "windows")] +mod win32; + +#[cfg(target_os = "linux")] +#[cfg(not(feature = "wayland"))] +mod x11; + +//#[cfg(target_os = "linux")] +//mod evdev; + +#[cfg(target_os = "macos")] +mod mac; + +#[macro_use] +extern crate lazy_static; + +pub trait Clipboard { + fn get_text(&self) -> Option; + fn set_text(&self, text: &str) -> Result<()>; + fn set_image(&self, image_path: &Path) -> Result<()>; + fn set_html(&self, html: &str, fallback_text: Option<&str>) -> Result<()>; +} + +#[allow(dead_code)] +pub struct ClipboardOptions { +} + +impl Default for ClipboardOptions { + fn default() -> Self { + Self {} + } +} + +#[cfg(target_os = "windows")] +pub fn get_injector(_options: InjectorCreationOptions) -> Result> { + info!("using Win32Injector"); + Ok(Box::new(win32::Win32Injector::new())) +} + +#[cfg(target_os = "macos")] +pub fn get_injector(_options: InjectorCreationOptions) -> Result> { + info!("using MacInjector"); + Ok(Box::new(mac::MacInjector::new())) +} + +#[cfg(target_os = "linux")] +#[cfg(not(feature = "wayland"))] +pub fn get_clipboard(options: ClipboardOptions) -> Result> { + info!("using X11NativeClipboard"); + Ok(Box::new(x11::native::X11NativeClipboard::new()?)) +} + +#[cfg(target_os = "linux")] +#[cfg(feature = "wayland")] +pub fn get_injector(options: InjectorCreationOptions) -> Result> { + info!("using EVDEVInjector"); + Ok(Box::new(evdev::EVDEVInjector::new(options)?)) +} diff --git a/espanso/Cargo.toml b/espanso/Cargo.toml index 8e9445f..8f26761 100644 --- a/espanso/Cargo.toml +++ b/espanso/Cargo.toml @@ -19,5 +19,6 @@ espanso-ui = { path = "../espanso-ui" } espanso-inject = { path = "../espanso-inject" } espanso-config = { path = "../espanso-config" } espanso-match = { path = "../espanso-match" } +espanso-clipboard = { path = "../espanso-clipboard" } maplit = "1.0.2" simplelog = "0.9.0" \ No newline at end of file diff --git a/espanso/src/main.rs b/espanso/src/main.rs index 918ab8d..c64c658 100644 --- a/espanso/src/main.rs +++ b/espanso/src/main.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{path::PathBuf, time::Duration}; use espanso_detect::{ event::{InputEvent, Status}, @@ -66,7 +66,7 @@ fn main() { let handle = std::thread::spawn(move || { let injector = get_injector(Default::default()).unwrap(); let mut source = get_source(SourceCreationOptions { - use_evdev: true, + //use_evdev: true, hotkeys: vec![ HotKey::new(1, "OPTION+SPACE").unwrap(), HotKey::new(2, "CTRL+OPTION+3").unwrap(), @@ -74,6 +74,7 @@ fn main() { ..Default::default() }) .unwrap(); + let clipboard = espanso_clipboard::get_clipboard(Default::default()).unwrap(); source.initialize().unwrap(); source .eventloop(Box::new(move |event: InputEvent| { @@ -91,7 +92,15 @@ fn main() { //injector.send_key_combination(&[keys::Key::Control, keys::Key::V], Default::default()).unwrap(); } } - InputEvent::HotKey(_) => {} + InputEvent::HotKey(hotkey) => { + if hotkey.hotkey_id == 2 { + println!("clip {:?}", clipboard.get_text()); + } else if hotkey.hotkey_id == 1 { + //clipboard.set_text("test text").unwrap(); + //clipboard.set_html("test text", Some("test text fallback")).unwrap(); + clipboard.set_image(&PathBuf::from("/home/freddy/insync/Development/Espanso/Images/icongreen.png")).unwrap(); + } + } } })) .unwrap();