Mercurial > tablet-emu
comparison src/bin/server.rs @ 18:3f7b7a3ad8fe
Build three binaries instead of using arguments.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 26 Aug 2021 22:15:55 +0200 |
parents | src/server.rs@0bce7fe96937 |
children | ba09079686a0 |
comparison
equal
deleted
inserted
replaced
17:0bce7fe96937 | 18:3f7b7a3ad8fe |
---|---|
1 // Tablet emulator, for people who don’t own one | |
2 // Copyright © 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | |
3 // | |
4 // This program is free software: you can redistribute it and/or modify | |
5 // it under the terms of the GNU Affero General Public License as published by | |
6 // the Free Software Foundation, either version 3 of the License, or | |
7 // (at your option) any later version. | |
8 // | |
9 // This program is distributed in the hope that it will be useful, | |
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 // GNU Affero General Public License for more details. | |
13 // | |
14 // You should have received a copy of the GNU Affero General Public License | |
15 // along with this program. If not, see <https://www.gnu.org/licenses/>. | |
16 | |
17 use input_linux::Key; | |
18 use std::io::{self, ErrorKind}; | |
19 use std::net::UdpSocket; | |
20 use tablet_emu::protocol::{Buttons, Event}; | |
21 use tablet_emu::state::State; | |
22 | |
23 pub fn run_server(address: &str) -> io::Result<()> { | |
24 let mut state = match State::new() { | |
25 Ok(state) => state, | |
26 Err(err) => { | |
27 match err.kind() { | |
28 ErrorKind::NotFound => { | |
29 eprintln!("Couldn’t find /dev/uinput: {}", err); | |
30 eprintln!("Maybe you forgot to `modprobe uinput`?"); | |
31 } | |
32 ErrorKind::PermissionDenied => { | |
33 eprintln!("Couldn’t open /dev/uinput for writing: {}", err); | |
34 eprintln!("Maybe you aren’t allowed to create input devices?"); | |
35 } | |
36 _ => eprintln!("Couldn’t open /dev/uinput for writing: {}", err), | |
37 } | |
38 std::process::exit(1); | |
39 } | |
40 }; | |
41 | |
42 let socket = UdpSocket::bind(address)?; | |
43 println!("Listening on {:?}", socket); | |
44 println!("Here is an example client: https://hg.linkmauve.fr/remote-gamepad"); | |
45 | |
46 let mut event: Event = Default::default(); | |
47 let mut last = Some((0., 0.)); | |
48 state.set_size(320, 240); | |
49 loop { | |
50 // TODO: Yolo-alignment. | |
51 let buf: &mut [u8; 16] = unsafe { std::mem::transmute(&mut event) }; | |
52 let (amount, source) = socket.recv_from(buf)?; | |
53 if amount != std::mem::size_of::<Event>() { | |
54 eprintln!("Invalid data length: {}", amount); | |
55 continue; | |
56 } | |
57 println!("{:?} from {:?}", event, source); | |
58 if event.buttons.contains(Buttons::A) { | |
59 state.select_tool(Key::ButtonToolPen); | |
60 } else if event.buttons.contains(Buttons::B) { | |
61 state.select_tool(Key::ButtonToolRubber); | |
62 } else if event.buttons.contains(Buttons::X) { | |
63 state.select_tool(Key::ButtonToolBrush); | |
64 } else if event.buttons.contains(Buttons::Y) { | |
65 state.select_tool(Key::ButtonToolPencil); | |
66 } else if event.buttons.contains(Buttons::SELECT) { | |
67 state.select_tool(Key::ButtonToolAirbrush); | |
68 } else if event.buttons.contains(Buttons::RESIZE) { | |
69 println!( | |
70 "set_size({}, {})", | |
71 event.touch.0 as i32, event.touch.1 as i32 | |
72 ); | |
73 state.set_size(event.touch.0 as i32, event.touch.1 as i32); | |
74 } | |
75 let (x, y) = event.touch; | |
76 if event.buttons.contains(Buttons::TOUCH) { | |
77 if let None = last { | |
78 state.press(x as f64, y as f64)?; | |
79 last = Some((x as f64, y as f64)); | |
80 continue; | |
81 } | |
82 } else { | |
83 if let Some((x, y)) = last { | |
84 state.release(x, y)?; | |
85 last = None; | |
86 continue; | |
87 } | |
88 } | |
89 state.motion(x as f64, y as f64)?; | |
90 last = Some((x as f64, y as f64)); | |
91 } | |
92 } | |
93 | |
94 pub fn main() { | |
95 let args: Vec<_> = std::env::args().collect(); | |
96 let address = if args.len() > 1 { | |
97 args[1].clone() | |
98 } else { | |
99 String::from("0.0.0.0:16150") | |
100 }; | |
101 run_server(&address).unwrap(); | |
102 } |