intitial implementation

This commit is contained in:
Robin Appelman 2020-03-20 22:43:09 +01:00
commit c49351606c
7 changed files with 961 additions and 4 deletions

642
Cargo.lock generated Normal file
View file

@ -0,0 +1,642 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785"
[[package]]
name = "arraydeque"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0ffd3d69bd89910509a5d31d1f1353f38ccffdd116dd0099bbd6627f7bd8ad8"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
dependencies = [
"nodrop",
]
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "bitflags"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec 0.5.1",
"constant_time_eq",
]
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "ctrlc"
version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a4ba686dff9fa4c1c9636ce1010b0cf98ceb421361b0bb3d6faeec43bd217a7"
dependencies = [
"nix 0.17.0",
"winapi",
]
[[package]]
name = "dirs"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
dependencies = [
"cfg-if",
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
dependencies = [
"cfg-if",
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "err-derive"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82f46c91bbed409ee74495549acbfcc7fae856e712e1df15afe75d0775eedc6c"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote 1.0.3",
"rustversion",
"syn 1.0.16",
"synstructure",
]
[[package]]
name = "evdev"
version = "0.10.1"
source = "git+https://github.com/myfreeweb/evdev?branch=uinput#4b905750a2103787e3e84241c60aaa79deb7c20c"
dependencies = [
"bitflags 0.8.2",
"fixedbitset",
"libc",
"nix 0.9.0",
"num",
"strum",
"strum_macros",
]
[[package]]
name = "evtype"
version = "0.1.0"
dependencies = [
"ctrlc",
"dirs",
"err-derive",
"evdev",
"keycode",
"main_error",
"nix 0.9.0",
"serde",
]
[[package]]
name = "fixedbitset"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "keycode"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62a2e321168faccd78d918d74559679e0e51c9f87989b6d58057c0a783721937"
dependencies = [
"arraydeque",
"arrayvec 0.4.12",
"bitflags 1.2.1",
"keycode_macro",
]
[[package]]
name = "keycode_macro"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f13c65ae4c1a08b7081d6c25eeb200f603d1985fbe60cadc6c0aee8fb2e4921f"
dependencies = [
"anyhow",
"heck",
"proc-macro2",
"quote 1.0.3",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
[[package]]
name = "main_error"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04"
[[package]]
name = "nix"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32"
dependencies = [
"bitflags 0.9.1",
"cfg-if",
"libc",
"void",
]
[[package]]
name = "nix"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
dependencies = [
"bitflags 1.2.1",
"cc",
"cfg-if",
"libc",
"void",
]
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "num"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
dependencies = [
"num-integer",
"num-traits",
"rand",
"rustc-serialize",
]
[[package]]
name = "num-complex"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656"
dependencies = [
"num-traits",
"rustc-serialize",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
dependencies = [
"num-bigint",
"num-integer",
"num-traits",
"rustc-serialize",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro-error"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
"syn-mid",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid 0.2.0",
]
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "redox_users"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]]
name = "rustversion"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
]
[[package]]
name = "serde"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
]
[[package]]
name = "strum"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da"
[[package]]
name = "strum_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8"
dependencies = [
"quote 0.3.15",
"syn 0.11.11",
]
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
dependencies = [
"quote 0.3.15",
"synom",
"unicode-xid 0.0.4",
]
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"unicode-xid 0.2.0",
]
[[package]]
name = "syn-mid"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
dependencies = [
"unicode-xid 0.0.4",
]
[[package]]
name = "synstructure"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
"proc-macro2",
"quote 1.0.3",
"syn 1.0.16",
"unicode-xid 0.2.0",
]
[[package]]
name = "unicode-segmentation"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -4,6 +4,20 @@ version = "0.1.0"
authors = ["Robin Appelman <robin@icewind.nl>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "evtype_daemon"
path = "src/daemon.rs"
[[bin]]
name = "evtype"
path = "src/client.rs"
[dependencies]
evdev = { git = "https://github.com/myfreeweb/evdev", branch = "uinput" }
serde = { version = "1.0", features = ["derive"] }
keycode = "0.3.0"
nix = "0.9.0"
err-derive = "0.2.3"
dirs = "2.0.2"
main_error = "0.1.0"
ctrlc = "3.1.4"

16
src/client.rs Normal file
View file

@ -0,0 +1,16 @@
use dirs::runtime_dir;
use main_error::MainError;
use std::io::Write;
use std::os::unix::net::UnixStream;
fn main() -> Result<(), MainError> {
let mut path = runtime_dir().ok_or("Can't get runtime directory")?;
path.push("evtype.sock");
let text = std::env::args().skip(1).next().unwrap_or_default();
let mut stream = UnixStream::connect(&path)?;
stream.write_all(text.as_bytes())?;
Ok(())
}

9
src/common.rs Normal file
View file

@ -0,0 +1,9 @@
use err_derive::Error;
#[derive(Clone, Debug, Error)]
pub enum Error {
#[error(display = "Unsupported character '{}'", _0)]
UnknownCharacter(char),
#[error(display = "Error sending keycode: {}", _0)]
Evdev(#[error(source)] nix::Error),
}

60
src/daemon.rs Normal file
View file

@ -0,0 +1,60 @@
use crate::common::Error;
use crate::keyboard::{char_to_key, create_device};
use dirs::runtime_dir;
use evdev::{data, raw, uinput};
use main_error::MainError;
use std::io::Read;
use std::os::unix::net::UnixListener;
use std::thread::sleep;
use std::time::Duration;
mod common;
mod keyboard;
const TYPE_DELAY: Duration = Duration::from_millis(10);
fn type_string(dev: &mut uinput::Device, text: &str) -> Result<(), Error> {
for c in text.chars() {
let (key, shift) = char_to_key(c)?;
dev.write(data::KEY, key as u16, 1)?;
if shift {
dev.write(data::KEY, data::KEY_LEFTSHIFT as u16, 1)?;
}
dev.write(data::SYNCHRONIZATION, data::SYN_REPORT as u16, 0)?;
sleep(TYPE_DELAY);
dev.write(data::KEY, key as u16, 0)?;
if shift {
dev.write(data::KEY, data::KEY_LEFTSHIFT as u16, 0)?;
}
dev.write(data::SYNCHRONIZATION, data::SYN_REPORT as u16, 0)?;
sleep(TYPE_DELAY);
}
Ok(())
}
fn main() -> Result<(), MainError> {
let mut keyboard = create_device()?;
let mut path = runtime_dir().ok_or("Can't get runtime directory")?;
path.push("evtype.sock");
let listener = UnixListener::bind(&path)?;
let mut incoming = listener.incoming();
println!("listening on {}", path.as_os_str().to_str().unwrap());
ctrlc::set_handler(move || {
let _ = std::fs::remove_file(&path);
std::process::exit(0);
})?;
let mut text_buffer = String::new();
while let Some(Ok(mut stream)) = incoming.next() {
text_buffer.clear();
stream.read_to_string(&mut text_buffer)?;
type_string(&mut keyboard, &text_buffer)?;
}
Ok(())
}

219
src/keyboard.rs Normal file
View file

@ -0,0 +1,219 @@
use crate::common::Error;
use evdev::raw::uinput_setup;
use evdev::{
data,
uinput::{Builder, Device},
uinput_ioctl,
};
pub fn char_to_key(c: char) -> Result<(data::Key, bool), Error> {
match c {
'0' => Ok((data::KEY_0, false)),
'1' => Ok((data::KEY_1, false)),
'2' => Ok((data::KEY_2, false)),
'3' => Ok((data::KEY_3, false)),
'4' => Ok((data::KEY_4, false)),
'5' => Ok((data::KEY_5, false)),
'6' => Ok((data::KEY_6, false)),
'7' => Ok((data::KEY_7, false)),
'8' => Ok((data::KEY_8, false)),
'9' => Ok((data::KEY_9, false)),
')' => Ok((data::KEY_0, true)),
'!' => Ok((data::KEY_1, true)),
'@' => Ok((data::KEY_2, true)),
'#' => Ok((data::KEY_3, true)),
'$' => Ok((data::KEY_4, true)),
'%' => Ok((data::KEY_5, true)),
'^' => Ok((data::KEY_6, true)),
'&' => Ok((data::KEY_7, true)),
'*' => Ok((data::KEY_8, true)),
'(' => Ok((data::KEY_9, true)),
'A' => Ok((data::KEY_A, true)),
'B' => Ok((data::KEY_B, true)),
'C' => Ok((data::KEY_C, true)),
'D' => Ok((data::KEY_D, true)),
'E' => Ok((data::KEY_E, true)),
'F' => Ok((data::KEY_F, true)),
'G' => Ok((data::KEY_G, true)),
'H' => Ok((data::KEY_H, true)),
'I' => Ok((data::KEY_I, true)),
'J' => Ok((data::KEY_J, true)),
'K' => Ok((data::KEY_K, true)),
'L' => Ok((data::KEY_L, true)),
'M' => Ok((data::KEY_M, true)),
'N' => Ok((data::KEY_N, true)),
'O' => Ok((data::KEY_O, true)),
'P' => Ok((data::KEY_P, true)),
'Q' => Ok((data::KEY_Q, true)),
'R' => Ok((data::KEY_R, true)),
'S' => Ok((data::KEY_S, true)),
'T' => Ok((data::KEY_T, true)),
'U' => Ok((data::KEY_U, true)),
'V' => Ok((data::KEY_V, true)),
'W' => Ok((data::KEY_W, true)),
'X' => Ok((data::KEY_X, true)),
'Y' => Ok((data::KEY_Y, true)),
'Z' => Ok((data::KEY_Z, true)),
'a' => Ok((data::KEY_A, false)),
'b' => Ok((data::KEY_B, false)),
'c' => Ok((data::KEY_C, false)),
'd' => Ok((data::KEY_D, false)),
'e' => Ok((data::KEY_E, false)),
'f' => Ok((data::KEY_F, false)),
'g' => Ok((data::KEY_G, false)),
'h' => Ok((data::KEY_H, false)),
'i' => Ok((data::KEY_I, false)),
'j' => Ok((data::KEY_J, false)),
'k' => Ok((data::KEY_K, false)),
'l' => Ok((data::KEY_L, false)),
'm' => Ok((data::KEY_M, false)),
'n' => Ok((data::KEY_N, false)),
'o' => Ok((data::KEY_O, false)),
'p' => Ok((data::KEY_P, false)),
'q' => Ok((data::KEY_Q, false)),
'r' => Ok((data::KEY_R, false)),
's' => Ok((data::KEY_S, false)),
't' => Ok((data::KEY_T, false)),
'u' => Ok((data::KEY_U, false)),
'v' => Ok((data::KEY_V, false)),
'w' => Ok((data::KEY_W, false)),
'x' => Ok((data::KEY_X, false)),
'y' => Ok((data::KEY_Y, false)),
'z' => Ok((data::KEY_Z, false)),
'-' => Ok((data::KEY_MINUS, false)),
'_' => Ok((data::KEY_MINUS, true)),
'=' => Ok((data::KEY_EQUAL, false)),
'+' => Ok((data::KEY_EQUAL, true)),
',' => Ok((data::KEY_COMMA, false)),
'<' => Ok((data::KEY_COMMA, true)),
'.' => Ok((data::KEY_DOT, false)),
'>' => Ok((data::KEY_DOT, true)),
'[' => Ok((data::KEY_LEFTBRACE, false)),
'{' => Ok((data::KEY_LEFTBRACE, true)),
']' => Ok((data::KEY_RIGHTBRACE, false)),
'}' => Ok((data::KEY_RIGHTBRACE, true)),
';' => Ok((data::KEY_SEMICOLON, false)),
':' => Ok((data::KEY_SEMICOLON, true)),
'\'' => Ok((data::KEY_APOSTROPHE, false)),
'"' => Ok((data::KEY_APOSTROPHE, true)),
'`' => Ok((data::KEY_GRAVE, false)),
'~' => Ok((data::KEY_GRAVE, true)),
'\\' => Ok((data::KEY_BACKSLASH, false)),
'|' => Ok((data::KEY_BACKSLASH, true)),
'/' => Ok((data::KEY_SLASH, false)),
'?' => Ok((data::KEY_SLASH, true)),
' ' => Ok((data::KEY_SPACE, false)),
'\n' => Ok((data::KEY_ENTER, false)),
c => Err(Error::UnknownCharacter(c)),
}
}
pub fn create_device() -> Result<Device, Error> {
let mut conf = uinput_setup::default();
conf.set_name("EvType")?;
conf.id.bustype = 0x16;
conf.id.vendor = 69;
conf.id.product = 69;
let builder = Builder::new(&std::path::Path::new("/dev/uinput"))?;
uinput_ioctl!(ui_set_evbit(builder.fd(), data::KEY.number()))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_0 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_1 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_2 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_3 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_4 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_5 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_6 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_7 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_8 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_9 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_0 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_1 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_2 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_3 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_4 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_5 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_6 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_7 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_8 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_9 as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_A as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_B as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_C as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_D as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_E as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_F as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_G as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_H as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_I as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_J as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_K as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_L as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_M as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_N as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_O as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_P as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Q as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_R as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_S as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_T as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_U as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_V as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_W as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_X as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Y as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Z as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_A as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_B as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_C as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_D as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_E as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_F as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_G as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_H as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_I as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_J as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_K as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_L as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_M as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_N as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_O as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_P as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Q as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_R as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_S as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_T as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_U as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_V as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_W as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_X as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Y as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_Z as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_MINUS as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_MINUS as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_EQUAL as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_EQUAL as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_COMMA as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_COMMA as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_DOT as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_DOT as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_LEFTBRACE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_LEFTBRACE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_RIGHTBRACE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_RIGHTBRACE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_SEMICOLON as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_SEMICOLON as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_APOSTROPHE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_APOSTROPHE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_GRAVE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_GRAVE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_BACKSLASH as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_BACKSLASH as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_SLASH as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_SLASH as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_SPACE as i32))?;
uinput_ioctl!(ui_set_keybit(builder.fd(), data::KEY_ENTER as i32))?;
Ok(builder.setup(conf)?)
}

View file

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}