First windows sender channel implementation
This commit is contained in:
parent
197bd5be34
commit
c05652618f
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -16,31 +16,8 @@ name = "espanso"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
|
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
|
||||||
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
|
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
|
||||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
|
@ -5,9 +5,6 @@ authors = ["Federico Terzi <federicoterzi96@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build="build.rs"
|
build="build.rs"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
|
||||||
winapi = { version = "0.3", features = ["winuser"] }
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -18,9 +18,11 @@ HWND window;
|
||||||
const wchar_t* const winclass = L"Espanso";
|
const wchar_t* const winclass = L"Espanso";
|
||||||
|
|
||||||
keypress_callback keypressCallback;
|
keypress_callback keypressCallback;
|
||||||
|
void * backend_instance;
|
||||||
|
|
||||||
void register_keypress_callback(keypress_callback callback) {
|
void register_keypress_callback(void * self, keypress_callback callback) {
|
||||||
keypressCallback = callback;
|
keypressCallback = callback;
|
||||||
|
backend_instance = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,7 +95,7 @@ LRESULT CALLBACK window_worker_procedure(HWND window, unsigned int msg, WPARAM w
|
||||||
// If a result is available, invoke the callback
|
// If a result is available, invoke the callback
|
||||||
if (result >= 1) {
|
if (result >= 1) {
|
||||||
//std::cout << buffer[0] << " " << buffer[1] << " res=" << result << " vk=" << raw->data.keyboard.VKey << " rsc=" << raw->data.keyboard.MakeCode << std::endl;
|
//std::cout << buffer[0] << " " << buffer[1] << " res=" << result << " vk=" << raw->data.keyboard.VKey << " rsc=" << raw->data.keyboard.MakeCode << std::endl;
|
||||||
keypressCallback(reinterpret_cast<int32_t*>(buffer.data()), buffer.size());
|
keypressCallback(backend_instance, reinterpret_cast<int32_t*>(buffer.data()), buffer.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +107,7 @@ LRESULT CALLBACK window_worker_procedure(HWND window, unsigned int msg, WPARAM w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t initialize() {
|
int32_t initialize_window() {
|
||||||
// Initialize the default keyboard layout
|
// Initialize the default keyboard layout
|
||||||
currentKeyboardLayout = GetKeyboardLayout(0);
|
currentKeyboardLayout = GetKeyboardLayout(0);
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,21 @@
|
||||||
* Called when a new keypress is made, the first argument is an int array,
|
* Called when a new keypress is made, the first argument is an int array,
|
||||||
* while the second is the size of the array.
|
* while the second is the size of the array.
|
||||||
*/
|
*/
|
||||||
typedef void (*keypress_callback)(int32_t *buffer, int32_t len);
|
typedef void (*keypress_callback)(void * self, int32_t *buffer, int32_t len);
|
||||||
|
|
||||||
extern keypress_callback keypressCallback;
|
extern keypress_callback keypressCallback;
|
||||||
|
extern void * backend_instance;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the callback that will be called when a keypress was made
|
* Register the callback that will be called when a keypress was made
|
||||||
*/
|
*/
|
||||||
extern "C" void register_keypress_callback(keypress_callback callback);
|
extern "C" void register_keypress_callback(void *self, keypress_callback callback);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the Windows worker's parameters
|
* Initialize the Windows worker's parameters
|
||||||
* return: 1 if OK, -1 otherwise.
|
* return: 1 if OK, -1 otherwise.
|
||||||
*/
|
*/
|
||||||
extern "C" int32_t initialize();
|
extern "C" int32_t initialize_window();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the event loop indefinitely. Blocking call.
|
* Start the event loop indefinitely. Blocking call.
|
||||||
|
|
14
src/keyboard/mod.rs
Normal file
14
src/keyboard/mod.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
mod windows;
|
||||||
|
|
||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
pub trait KeyboardBackend {
|
||||||
|
fn initialize(&self);
|
||||||
|
fn start(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn get_backend(sender: mpsc::Sender<char>) -> impl KeyboardBackend{
|
||||||
|
windows::WindowsKeyboardBackend{sender }
|
||||||
|
}
|
44
src/keyboard/windows.rs
Normal file
44
src/keyboard/windows.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
use std::thread;
|
||||||
|
use std::sync::mpsc;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct WindowsKeyboardBackend {
|
||||||
|
pub sender: mpsc::Sender<char>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl super::KeyboardBackend for WindowsKeyboardBackend {
|
||||||
|
fn initialize(&self) {
|
||||||
|
unsafe {
|
||||||
|
register_keypress_callback(self,keypress_callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start(&self) {
|
||||||
|
thread::spawn(|| {
|
||||||
|
unsafe {
|
||||||
|
initialize_window();
|
||||||
|
eventloop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Native bridge code
|
||||||
|
|
||||||
|
extern fn keypress_callback(_self: *mut WindowsKeyboardBackend, raw_buffer: *const i32, len: i32) {
|
||||||
|
unsafe {
|
||||||
|
// Convert the received buffer to a character
|
||||||
|
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
||||||
|
let r = std::char::from_u32(buffer[0] as u32).unwrap();
|
||||||
|
|
||||||
|
// Send the char through the channel
|
||||||
|
(*_self).sender.send(r).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link(name="winbridge", kind="static")]
|
||||||
|
extern {
|
||||||
|
fn register_keypress_callback(s: *const WindowsKeyboardBackend, cb: extern fn(_self: *mut WindowsKeyboardBackend, *const i32, i32));
|
||||||
|
fn initialize_window();
|
||||||
|
fn eventloop();
|
||||||
|
}
|
35
src/main.rs
35
src/main.rs
|
@ -1,26 +1,25 @@
|
||||||
extern fn keypress_callback(raw_buffer: *const i32, len: i32) {
|
use std::thread::sleep;
|
||||||
unsafe {
|
use std::time::Duration;
|
||||||
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
use crate::keyboard::KeyboardBackend;
|
||||||
println!("{}", std::char::from_u32(buffer[0] as u32).unwrap());
|
use std::sync::mpsc;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[link(name="winbridge", kind="static")]
|
mod keyboard;
|
||||||
extern {
|
|
||||||
fn initialize();
|
|
||||||
fn eventloop();
|
|
||||||
fn register_keypress_callback(cb: extern fn(*const i32, i32));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world from Rust!");
|
println!("Hello, world from Rust!");
|
||||||
|
|
||||||
// calling the function from foo library
|
let (sender, receiver) = mpsc::channel();
|
||||||
unsafe {
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
register_keypress_callback(keypress_callback);
|
let keyboard = keyboard::get_backend(sender);
|
||||||
|
keyboard.initialize();
|
||||||
|
keyboard.start();
|
||||||
|
|
||||||
eventloop();
|
loop {
|
||||||
};
|
match receiver.recv() {
|
||||||
|
Ok(c) => {
|
||||||
|
println!("Yeah {}",c);
|
||||||
|
},
|
||||||
|
Err(_) => panic!("Worker threads disconnected before the solution was found!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user