From 1c5252b7b0e308fedf13550d3956b5470dcf4a2b Mon Sep 17 00:00:00 2001 From: xdavidwu Date: Thu, 19 May 2022 14:08:22 +0800 Subject: [PATCH] add pointer controlling over udp --- .gitignore | 2 ++ Makefile | 6 +++-- cmd/pointerd/main.ha | 58 ++++++++++++++++++++++++++++++++++++++++ proto/control/types.ha | 18 +++++++++++++ tools/pointerc/main.ha | 60 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 cmd/pointerd/main.ha create mode 100644 proto/control/types.ha create mode 100644 tools/pointerc/main.ha diff --git a/.gitignore b/.gitignore index 532c959..6274f75 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /evdev-dump-events /uinput-pointer /gy-801-dump +/pointerc +/pointerd diff --git a/Makefile b/Makefile index b723c90..aa71dc1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ -evdev-dump-events uinput-pointer: +evdev-dump-events uinput-pointer pointerc: hare build -levdev -o $@ tools/$@/ gy-801-dump: hare build -o $@ tools/$@/ -.PHONY: evdev-dump-events uinput-pointer gy-801-dump +pointerd: + hare build -levdev -o $@ cmd/$@/ +.PHONY: evdev-dump-events uinput-pointer gy-801-dump pointerd pointerc diff --git a/cmd/pointerd/main.ha b/cmd/pointerd/main.ha new file mode 100644 index 0000000..a402cca --- /dev/null +++ b/cmd/pointerd/main.ha @@ -0,0 +1,58 @@ +use evdev; +use evdev::uinput; +use fmt; +use io; +use net; +use net::ip; +use net::udp; +use proto::control; +use rt; +use time; + +export fn main() void = { + const evdev = evdev::new(); + defer evdev::destroy(evdev); + evdev::set_name(evdev, "motion-control pointer"); + evdev::enable_event_type(evdev, evdev::EV_REL)!; + evdev::enable_event_code(evdev, evdev::EV_REL, evdev::REL_X, null)!; + evdev::enable_event_code(evdev, evdev::EV_REL, evdev::REL_Y, null)!; + evdev::enable_event_type(evdev, evdev::EV_KEY)!; + evdev::enable_event_code(evdev, evdev::EV_KEY, evdev::BTN_LEFT, null)!; + evdev::enable_event_code(evdev, evdev::EV_KEY, evdev::BTN_MIDDLE, null)!; + evdev::enable_event_code(evdev, evdev::EV_KEY, evdev::BTN_RIGHT, null)!; + + const uinput = match (uinput::create_from_device(evdev, uinput::OPEN_MANAGED)) { + case let uinput: uinput::uinput => + yield uinput; + case let err: rt::errno => + fmt::fatalf("Failed to create uinput dev: {}", rt::strerror(err)); + }; + defer uinput::destroy(uinput); + + const addr = ip::ANY_V6, port = control::DEFAULT_PORT; + const sock = match(udp::listen(addr, port)) { + case let sock: io::file => + yield sock; + case let err: net::error => + fmt::fatalf("Failed to listen on {}:{}: {}", + ip::string(addr), port, net::strerror(err)); + }; + defer io::close(sock)!; + + let buf = control::request {...}; + for (true) { + const sz = udp::recvfrom(sock, buf.bytes, null, null)!; + if (sz != size(control::request)) { + fmt::errorln("Unexpected read size")!; + continue; + }; + switch (buf.code) { + case control::code::RELATIVE_MOVEMENT => + uinput::write_event(uinput, evdev::EV_REL, evdev::REL_X, buf.x)!; + uinput::write_event(uinput, evdev::EV_REL, evdev::REL_Y, buf.y)!; + uinput::write_event(uinput, evdev::EV_SYN, evdev::SYN_REPORT, 0)!; + case => + fmt::errorfln("Unrecognized control code: {}", buf.code)!; + }; + }; +}; diff --git a/proto/control/types.ha b/proto/control/types.ha new file mode 100644 index 0000000..f5b0354 --- /dev/null +++ b/proto/control/types.ha @@ -0,0 +1,18 @@ +export def DEFAULT_PORT: u16 = 0x519; + +export type code = enum u8 { + RELATIVE_MOVEMENT = 0, +}; + +export type request = union { + struct { + code: u8, + union { + struct { + x: i8, + y: i8, + }, + }, + }, + bytes: [3]u8, +}; diff --git a/tools/pointerc/main.ha b/tools/pointerc/main.ha new file mode 100644 index 0000000..24a9180 --- /dev/null +++ b/tools/pointerc/main.ha @@ -0,0 +1,60 @@ +use fmt; +use io; +use net; +use net::ip; +use net::udp; +use os; +use proto::control; +use strconv; + +export fn main() int = { + if (len(os::args) != 5) { + fmt::fatalf("Usage: {} addr port x y", os::args[0]); + }; + const addr = match (ip::parse(os::args[1])) { + case let addr: ip::addr => + yield addr; + case ip::invalid => + fmt::fatalf("Invalid address {}", os::args[1]); + }; + const port = match (strconv::stou16(os::args[2])) { + case let port: u16 => + yield port; + case => + fmt::fatalf("Invalid port {}", os::args[2]); + }; + const x = match (strconv::stoi8(os::args[3])) { + case let n: i8 => + yield n; + case => + fmt::fatalf("Invalid x {}", os::args[3]); + }; + const y = match (strconv::stoi8(os::args[4])) { + case let n: i8 => + yield n; + case => + fmt::fatalf("Invalid y {}", os::args[4]); + }; + + const buf = control::request { + code = control::code::RELATIVE_MOVEMENT, + x = x, + y = y, + }; + + const sock = match (udp::connect(addr, port)) { + case let s: io::file => + yield s; + case let err: net::error => + fmt::fatalf("Cannot connect() {}:{}: {}", ip::string(addr), port, net::strerror(err)); + }; + defer io::close(sock)!; + + match (udp::send(sock, buf.bytes)) { + case let err: net::error => + fmt::fatalf("Cannot send(): {}", net::strerror(err)); + case size => + yield; + }; + return 0; +}; -- 2.45.2