Add basic typing functionality on linux

This commit is contained in:
Federico Terzi 2019-09-01 16:50:20 +02:00
parent dc2868b217
commit 0ba18eba51
5 changed files with 47 additions and 4 deletions

View File

@ -27,9 +27,11 @@ fn print_config() {
#[cfg(target_os = "linux")]
fn print_config() {
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu/");
println!("cargo:rustc-link-lib=static=linuxbridge");
println!("cargo:rustc-link-lib=dylib=X11");
println!("cargo:rustc-link-lib=dylib=Xtst");
println!("cargo:rustc-link-lib=dylib=xdo");
}
fn main()

View File

@ -1,5 +1,6 @@
#include "bridge.h"
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <array>
@ -12,6 +13,9 @@
#include <X11/extensions/record.h>
#include <X11/extensions/XTest.h>
#include <X11/XKBlib.h>
extern "C" { // Needed to avoid C++ compiler name mangling
#include <xdo.h>
}
/*
This code uses the X11 Record Extension to receive keyboard
@ -46,6 +50,8 @@ Display *ctrl_disp = NULL;
XRecordRange *record_range;
XRecordContext context;
xdo_t * xdo_context;
// Callback invoked when a new key event occur.
void event_callback (XPointer, XRecordInterceptData*);
@ -59,6 +65,8 @@ void register_keypress_callback(void * self, KeypressCallback callback) {
int32_t initialize() {
setlocale(LC_ALL, "");
/*
Open the connections to the X server.
RE recommends to open 2 connections to the X server:
@ -107,6 +115,8 @@ int32_t initialize() {
if (!context) {
return -5;
}
xdo_context = xdo_new(NULL);
}
int32_t eventloop() {
@ -123,6 +133,7 @@ void cleanup() {
XFree (record_range);
XCloseDisplay(data_disp);
XCloseDisplay(ctrl_disp);
xdo_free(xdo_context);
}
void event_callback(XPointer p, XRecordInterceptData *hook)
@ -182,4 +193,14 @@ void event_callback(XPointer p, XRecordInterceptData *hook)
}
XRecordFreeData(hook);
}
void send_string(const char * string) {
xdo_enter_text_window(xdo_context, CURRENTWINDOW, string, 0);
}
void delete_string(int32_t count) {
for (int i = 0; i<count; i++) {
xdo_send_keysequence_window(xdo_context, CURRENTWINDOW, "BackSpace", 0);
}
}

View File

@ -32,4 +32,14 @@ extern void * interceptor_instance;
*/
extern "C" void register_keypress_callback(void *self, KeypressCallback callback);
/*
* Type the given string by simulating Key Presses
*/
extern "C" void send_string(const char * string);
/*
* Send the backspace keypress, *count* times.
*/
extern "C" void delete_string(int32_t count);
#endif //ESPANSO_BRIDGE_H

View File

@ -1,5 +1,7 @@
use std::thread;
use std::sync::mpsc;
use std::os::raw::c_char;
use std::ffi::CString;
#[repr(C)]
pub struct LinuxKeyboardInterceptor {
@ -28,12 +30,15 @@ pub struct LinuxKeyboardSender {
impl super::KeyboardSender for LinuxKeyboardSender {
fn send_string(&self, s: &str) {
println!("{}", s);
let res = CString::new(s);
match res {
Ok(cstr) => unsafe { send_string(cstr.as_ptr()); }
Err(e) => panic!(e.to_string())
}
}
fn delete_string(&self, count: i32) {
unsafe {delete_string(count)}
}
}
@ -60,4 +65,6 @@ extern {
fn initialize();
fn eventloop();
fn cleanup();
fn send_string(string: *const c_char);
fn delete_string(count: i32);
}

View File

@ -22,7 +22,10 @@ fn main() {
let engine = Engine::new(&sender);
let matches = vec![Match{trigger:"e'".to_owned(), result: "è".to_owned()}, Match{trigger:":lol".to_owned(), result: "😂".to_owned()}];
let matches = vec![Match{trigger:"e'".to_owned(), result: "è".to_owned()},
Match{trigger:":lol".to_owned(), result: "😂".to_owned()},
Match{trigger:":lll".to_owned(), result: "yo".to_owned()},
];
let mut matcher = ScrollingMatcher::new(&matches, &engine);
matcher.watch(&rxc);