intercept: implement intercept functionality with libevdev

This commit is contained in:
Asmir A 2023-09-03 12:46:08 +02:00
parent 4553a1df64
commit df0c3657b4

View File

@ -1,26 +1,29 @@
const std = @import("std"); const std = @import("std");
const print = std.debug.print; const c = @cImport({
const input = @cImport(@cInclude("linux/input.h")); @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 CapsLockDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_CAPSLOCK, .value = 1, .time = undefined };
const CapsLockUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_CAPSLOCK, .value = 0, .time = undefined }; const CapsLockUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_CAPSLOCK, .value = 0, .time = undefined };
const EscDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_ESC, .value = 1, .time = undefined }; const EscDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_ESC, .value = 1, .time = undefined };
const EscUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_ESC, .value = 0, .time = undefined }; const EscUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_ESC, .value = 0, .time = undefined };
const LShiftDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_LEFTSHIFT, .value = 1, .time = undefined }; const LShiftDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_LEFTSHIFT, .value = 1, .time = undefined };
const LShiftUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_LEFTSHIFT, .value = 0, .time = undefined }; const LShiftUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_LEFTSHIFT, .value = 0, .time = undefined };
const RShiftDown = input.input_event{ .type = input.EV_KEY, .code = input.KEY_RIGHTSHIFT, .value = 1, .time = undefined }; const RShiftDown = c.input_event{ .type = c.EV_KEY, .code = c.KEY_RIGHTSHIFT, .value = 1, .time = undefined };
const RShiftUp = input.input_event{ .type = input.EV_KEY, .code = input.KEY_RIGHTSHIFT, .value = 0, .time = undefined }; const RShiftUp = c.input_event{ .type = c.EV_KEY, .code = c.KEY_RIGHTSHIFT, .value = 0, .time = undefined };
const Syn = input.input_event{ .type = input.EV_SYN, .code = input.SYN_REPORT, .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); return (e1.*.type == e2.*.type) and (e1.*.code == e2.*.code) and (e1.*.value == e2.*.value);
} }
fn event_read(event: *input.input_event) !void { //fn event_read(event: *c.input_event) !void {
event.* = try std.io.getStdIn().reader().readStruct(@TypeOf(event.*)); // 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.*); try std.io.getStdOut().writer().writeStruct(event.*);
} }
@ -32,22 +35,60 @@ fn write_esc() !void {
try event_write(&EscUp); try event_write(&EscUp);
} }
fn device_open() !void {}
pub fn main() !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_lshift: bool = undefined;
var write_esc_rshift: bool = undefined; var write_esc_rshift: bool = undefined;
var is_lshift_down: bool = false; var is_lshift_down: bool = false;
var is_rshift_down: bool = false; var is_rshift_down: bool = false;
while (true) { outer: while (true) {
try event_read(&event); var event: c.input_event = undefined;
if (event.type == input.EV_MSC and event.type == input.MSC_SCAN) { var rc = c.libevdev_next_event(dev, c.LIBEVDEV_READ_FLAG_NORMAL | c.LIBEVDEV_READ_FLAG_BLOCKING, @ptrCast(&event));
continue;
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); try event_write(&event);
continue; continue :outer;
} }
write_esc_lshift = event_equal(&event, &LShiftUp) and is_lshift_down; 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); is_rshift_down = event_equal(&event, &RShiftDown);
if (event_equal(&event, &CapsLockUp) or event_equal(&event, &CapsLockDown)) { if (event_equal(&event, &CapsLockUp) or event_equal(&event, &CapsLockDown)) {
event.code = input.KEY_LEFTMETA; event.code = c.KEY_LEFTMETA;
} }
try event_write(&event); try event_write(&event);