116 lines
4.0 KiB
Zig
116 lines
4.0 KiB
Zig
const std = @import("std");
|
|
const c = @cImport({
|
|
@cInclude("linux/input.h");
|
|
@cInclude("libevdev-1.0/libevdev/libevdev.h");
|
|
@cInclude("errno.h");
|
|
});
|
|
|
|
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 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: *c.input_event) !void {
|
|
// event.* = try std.io.getStdIn().reader().readStruct(@TypeOf(event.*));
|
|
//}
|
|
|
|
fn event_write(event: *const c.input_event) !void {
|
|
try std.io.getStdOut().writer().writeStruct(event.*);
|
|
}
|
|
|
|
fn write_esc() !void {
|
|
std.time.sleep(20000);
|
|
try event_write(&EscDown);
|
|
try event_write(&Syn);
|
|
std.time.sleep(20000);
|
|
try event_write(&EscUp);
|
|
}
|
|
|
|
fn device_open() !void {}
|
|
|
|
pub fn main() !void {
|
|
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;
|
|
|
|
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 (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 :outer;
|
|
}
|
|
|
|
write_esc_lshift = event_equal(&event, &LShiftUp) and is_lshift_down;
|
|
write_esc_rshift = event_equal(&event, &RShiftUp) and is_rshift_down;
|
|
is_lshift_down = event_equal(&event, &LShiftDown);
|
|
is_rshift_down = event_equal(&event, &RShiftDown);
|
|
|
|
if (event_equal(&event, &CapsLockUp) or event_equal(&event, &CapsLockDown)) {
|
|
event.code = c.KEY_LEFTMETA;
|
|
}
|
|
|
|
try event_write(&event);
|
|
|
|
if (write_esc_lshift) {
|
|
write_esc_lshift = false;
|
|
try write_esc();
|
|
}
|
|
|
|
if (write_esc_rshift) {
|
|
write_esc_rshift = false;
|
|
try write_esc();
|
|
}
|
|
}
|
|
}
|