hid_io_core/
lib.rs

1/* Copyright (C) 2017-2023 by Jacob Alexander
2 *
3 * This file is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This file is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#![feature(extract_if)]
18
19// ----- Crates -----
20
21#[macro_use]
22extern crate log;
23
24use std::sync::atomic::Ordering;
25
26pub use tokio;
27
28// ----- Modules -----
29
30/// capnp interface for other programs to hook into
31pub mod api;
32
33/// communication with hidapi compatable devices
34pub mod device;
35
36/// logging functions
37pub mod logging;
38
39/// mpmc mailbox implementation for hid-io-core (e.g. packet broadcast with filters)
40pub mod mailbox;
41
42/// built-in features and command handlers
43pub mod module;
44
45/// Compile time information
46pub mod built_info {
47    // This file is generated at build time using build.rs
48    include!(concat!(env!("OUT_DIR"), "/built.rs"));
49}
50
51/// [AUTO GENERATED]
52#[cfg(feature = "api")]
53pub mod common_capnp {
54    #![allow(clippy::all)]
55    include!(concat!(env!("OUT_DIR"), "/common_capnp.rs"));
56}
57
58/// [AUTO GENERATED]
59#[cfg(feature = "api")]
60pub mod daemon_capnp {
61    #![allow(clippy::all)]
62    include!(concat!(env!("OUT_DIR"), "/daemon_capnp.rs"));
63}
64
65/// [AUTO GENERATED]
66#[cfg(feature = "api")]
67pub mod hidio_capnp {
68    #![allow(clippy::all)]
69    include!(concat!(env!("OUT_DIR"), "/hidio_capnp.rs"));
70}
71
72/// [AUTO GENERATED]
73#[cfg(feature = "api")]
74pub mod keyboard_capnp {
75    #![allow(clippy::all)]
76    include!(concat!(env!("OUT_DIR"), "/keyboard_capnp.rs"));
77}
78
79// ----- Functions -----
80
81pub use hid_io_protocol::HidIoCommandId;
82use lazy_static::lazy_static;
83use std::sync::atomic::AtomicBool;
84use std::sync::Arc;
85
86lazy_static! {
87    /// Any thread can set this to false to signal shutdown
88    pub static ref RUNNING: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
89}
90
91/// Supported Ids by hid-io-core
92/// This is used to determine all supported ids (always recursive).
93pub fn supported_ids() -> Vec<HidIoCommandId> {
94    let mut ids = Vec::new();
95
96    ids.extend(api::supported_ids().iter().cloned());
97    ids.extend(device::supported_ids(true).iter().cloned());
98    ids.extend(module::supported_ids(true).iter().cloned());
99
100    // Sort, then deduplicate
101    ids.sort_unstable();
102    ids.dedup();
103
104    ids
105}
106
107/// Main entry-point for the hid-io-core library
108pub async fn initialize(mailbox: mailbox::Mailbox) -> Result<(), std::io::Error> {
109    // Setup signal handler
110    let r = RUNNING.clone();
111    ctrlc::set_handler(move || {
112        r.store(false, Ordering::SeqCst);
113    })
114    .expect("Error setting Ctrl-C handler");
115    println!("Press Ctrl-C to exit...");
116
117    // Wait until completion
118    let (_, _, _) = tokio::join!(
119        // Initialize Modules
120        module::initialize(mailbox.clone()),
121        // Initialize Device monitoring
122        device::initialize(mailbox.clone()),
123        // Initialize Cap'n'Proto API Server
124        api::initialize(mailbox),
125    );
126    Ok(())
127}