From df0c3657b46ef1f40ca9aecad09ebde27cd7987d Mon Sep 17 00:00:00 2001 From: Asmir A Date: Sun, 3 Sep 2023 12:46:08 +0200 Subject: [PATCH] intercept: implement intercept functionality with libevdev --- src/main.zig | 89 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/src/main.zig b/src/main.zig index 87c3a27..e13e770 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,26 +1,29 @@ const std = @import("std"); -const print = std.debug.print; -const input = @cImport(@cInclude("linux/input.h")); +const c = @cImport({ + @cInclude("linux/input.h"); + @cInclude("libevdev-1.0/libevdev/libevdev.h"); + @cInclude("errno.h"); +}); -const CapsLockDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_CAPSLOCK, .value = 1, .time = undefined }; -const CapsLockUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_CAPSLOCK, .value = 0, .time = undefined }; -const EscDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_ESC, .value = 1, .time = undefined }; -const EscUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_ESC, .value = 0, .time = undefined }; -const LShiftDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_LEFTSHIFT, .value = 1, .time = undefined }; -const LShiftUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_LEFTSHIFT, .value = 0, .time = undefined }; -const RShiftDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_RIGHTSHIFT, .value = 1, .time = undefined }; -const RShiftUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_RIGHTSHIFT, .value = 0, .time = undefined }; -const Syn = input.input_event{ .type = input.EV_SYN, .code = input.SYN_REPORT, .value = 0, .time = undefined }; +const CapsLockDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_CAPSLOCK, .value = 1, .time = undefined }; +const CapsLockUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_CAPSLOCK, .value = 0, .time = undefined }; +const EscDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_ESC, .value = 1, .time = undefined }; +const EscUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_ESC, .value = 0, .time = undefined }; +const LShiftDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_LEFTSHIFT, .value = 1, .time = undefined }; +const LShiftUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_LEFTSHIFT, .value = 0, .time = undefined }; +const RShiftDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_RIGHTSHIFT, .value = 1, .time = undefined }; +const RShiftUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_RIGHTSHIFT, .value = 0, .time = undefined }; +const Syn = c.input_event{ .type = c.EV_SYN, .code = c.SYN_REPORT, .value = 0, .time = undefined }; -fn event_equal(e1: *const input.input_event, e2: *const input.input_event) bool { +fn event_equal(e1: *const c.input_event, e2: *const c.input_event) bool { return (e1.*.type == e2.*.type) and (e1.*.code == e2.*.code) and (e1.*.value == e2.*.value); } -fn event_read(event: *input.input_event) !void { - event.* = try std.io.getStdIn().reader().readStruct(@TypeOf(event.*)); -} +//fn event_read(event: *c.input_event) !void { +// event.* = try std.io.getStdIn().reader().readStruct(@TypeOf(event.*)); +//} -fn event_write(event: *const input.input_event) !void { +fn event_write(event: *const c.input_event) !void { try std.io.getStdOut().writer().writeStruct(event.*); } @@ -32,22 +35,60 @@ fn write_esc() !void { try event_write(&EscUp); } +fn device_open() !void {} + pub fn main() !void { - var event: input.input_event = undefined; + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + const args = try std.process.argsAlloc(allocator); + + if (args.len != 2) { + std.debug.print("error: expected one argument", .{}); + std.os.exit(1); + } + const dev_name = args[1]; + var dev_fd = try std.fs.openFileAbsolute(dev_name, .{}); + + const dev = c.libevdev_new(); + if (c.libevdev_set_fd(dev, dev_fd.handle) < 0) { + std.debug.print("evdev: failed creating device from descriptor", .{}); + std.os.exit(1); + } + if (c.libevdev_grab(dev, c.LIBEVDEV_GRAB) < 0) { + std.debug.print("evdev: failed grabbing device", .{}); + std.os.exit(1); + } + var write_esc_lshift: bool = undefined; var write_esc_rshift: bool = undefined; var is_lshift_down: bool = false; var is_rshift_down: bool = false; - while (true) { - try event_read(&event); - if (event.type == input.EV_MSC and event.type == input.MSC_SCAN) { - continue; + outer: while (true) { + var event: c.input_event = undefined; + var rc = c.libevdev_next_event(dev, c.LIBEVDEV_READ_FLAG_NORMAL | c.LIBEVDEV_READ_FLAG_BLOCKING, @ptrCast(&event)); + + while (rc == c.LIBEVDEV_READ_STATUS_SYNC) { + rc = c.libevdev_next_event(dev, c.LIBEVDEV_READ_FLAG_SYNC, @ptrCast(&event)); } - if (event.type != input.EV_KEY) { + if (rc == -c.EAGAIN) { + continue :outer; + } + + if (rc != c.LIBEVDEV_READ_STATUS_SUCCESS) { + break :outer; + } + + if (event.type == c.EV_MSC and event.type == c.MSC_SCAN) { + continue :outer; + } + + if (event.type != c.EV_KEY) { try event_write(&event); - continue; + continue :outer; } write_esc_lshift = event_equal(&event, &LShiftUp) and is_lshift_down; @@ -56,7 +97,7 @@ pub fn main() !void { is_rshift_down = event_equal(&event, &RShiftDown); if (event_equal(&event, &CapsLockUp) or event_equal(&event, &CapsLockDown)) { - event.code = input.KEY_LEFTMETA; + event.code = c.KEY_LEFTMETA; } try event_write(&event);