Skip to main content

hidpipe_shared/
lib.rs

1use std::{slice, mem};
2use std::io::{Result, Write};
3use std::os::unix::net::UnixStream;
4use input_linux::{
5    InputProperty, EventKind, AbsoluteAxis, Key, RelativeAxis, ForceFeedbackKind,
6    MiscKind, LedKind, SoundKind, SwitchKind, InputId, bitmask::BitmaskTrait
7};
8use input_linux::sys::{input_event, timeval, ff_effect};
9
10#[repr(C)]
11#[derive(Debug)]
12pub struct ClientHello {
13    pub version: u32
14}
15
16#[repr(C)]
17#[derive(Debug)]
18pub struct ServerHello {
19    pub version: u32
20}
21
22#[repr(u32)]
23#[derive(Debug)]
24pub enum MessageType {
25    AddDevice,
26    RemoveDevice,
27    InputEvent,
28    FFUpload,
29    FFErase
30}
31
32#[repr(C)]
33#[derive(Debug)]
34pub struct FFUpload {
35    pub id: u64,
36    pub request_id: u32,
37    pub effect: ff_effect
38}
39
40#[repr(C)]
41#[derive(Debug)]
42pub struct FFErase {
43    pub id: u64,
44    pub request_id: u32,
45    pub effect_id: u32,
46}
47
48#[repr(C)]
49#[derive(Debug)]
50pub struct AddDevice {
51    pub id: u64,
52    pub evbits: <EventKind as BitmaskTrait>::Array,
53    pub keybits: <Key as BitmaskTrait>::Array,
54    pub relbits: <RelativeAxis as BitmaskTrait>::Array,
55    pub absbits: <AbsoluteAxis  as BitmaskTrait>::Array,
56    pub mscbits: <MiscKind as BitmaskTrait>::Array,
57    pub ledbits: <LedKind as BitmaskTrait>::Array,
58    pub sndbits: <SoundKind as BitmaskTrait>::Array,
59    pub swbits: <SwitchKind as BitmaskTrait>::Array,
60    pub propbits: <InputProperty as BitmaskTrait>::Array,
61    pub ffbits: <ForceFeedbackKind as BitmaskTrait>::Array,
62    pub input_id: InputId,
63    pub ff_effects: u32,
64    pub name: [u8; 80],
65}
66
67#[repr(C)]
68#[derive(Debug)]
69pub struct RemoveDevice {
70    pub id: u64
71}
72
73#[repr(C)]
74#[derive(Debug)]
75pub struct InputEvent {
76    pub time_sec: i64,
77    pub time_usec: i64,
78    pub id: u64,
79    pub value: i32,
80    pub ty: u16,
81    pub code: u16,
82}
83
84impl InputEvent {
85    pub fn new(id: u64, e: input_event) -> InputEvent {
86        InputEvent {
87            id,
88            ty: e.type_,
89            code: e.code,
90            value: e.value,
91            time_sec: e.time.tv_sec,
92            time_usec: e.time.tv_usec,
93        }
94    }
95    pub fn to_input_event(&self) -> input_event {
96        input_event {
97            time: timeval {
98                tv_sec: self.time_sec,
99                tv_usec: self.time_usec
100            },
101            type_: self.ty,
102            code: self.code,
103            value: self.value,
104        }
105    }
106}
107
108pub fn empty_input_event() -> input_event {
109    input_event {
110        time: timeval { tv_sec: 0, tv_usec: 0 },
111        type_: 0,
112        code: 0,
113        value: 0,
114    }
115}
116
117pub fn struct_to_socket<T>(socket: &mut UnixStream, data: &T) -> Result<()> {
118    let size = mem::size_of::<T>();
119    // SAFETY:
120    // We are taking a ref, so it is valid for reads, properly aligned, and nobody can write to it
121    let v = unsafe {
122        slice::from_raw_parts(data as *const T as *const u8, size)
123    };
124    socket.write_all(v)
125}