Compare commits

...

10 Commits

4 changed files with 54 additions and 39 deletions

2
debug.sh Executable file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
lldb -- ./zig-out/bin/zremap /dev/input/by-path/platform-i8042-serio-0-event-kbd

6
flake.lock generated
View File

@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1693060755, "lastModified": 1696419054,
"narHash": "sha256-KNsbfqewEziFJEpPR0qvVz4rx0x6QXxw1CcunRhlFdk=", "narHash": "sha256-EdR+dIKCfqL3voZUDYwcvgRDOektQB9KbhBVcE0/3Mo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c66ccfa00c643751da2fd9290e096ceaa30493fc", "rev": "7131f3c223a2d799568e4b278380cd9dac2b8579",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -11,17 +11,22 @@
version = "0.1"; version = "0.1";
src = self; src = self;
nativeBuildInputs = [zig.hook]; nativeBuildInputs = [zig.hook];
buildInputs = [libevdev]; buildInputs = [libevdev pkg-config];
buildPhase = ''
NIX_CFLAGS_COMPILE="-isystem $(pkg-config --variable=includedir libevdev)/libevdev-1.0 $NIX_CFLAGS_COMPILE"
'';
}; };
devShells.x86_64-linux.default = with import nixpkgs {system = "x86_64-linux";}; devShells.x86_64-linux.default = with import nixpkgs {system = "x86_64-linux";};
mkShell { mkShell {
nativeBuildInputs = [zig lldb];
buildInputs = [ buildInputs = [
libevdev libevdev
zig pkg-config
]; ];
shellHook = '' shellHook = ''
NIX_CFLAGS_COMPILE="-isystem $(pkg-config --variable=includedir libevdev)/libevdev-1.0 $NIX_CFLAGS_COMPILE"
echo "happy hacking!" echo "happy hacking!"
''; '';
}; };

View File

@ -1,42 +1,59 @@
const std = @import("std"); const std = @import("std");
const c = @cImport({ const c = @cImport({
@cInclude("linux/input.h"); @cInclude("linux/input.h");
@cInclude("libevdev-1.0/libevdev/libevdev.h"); @cInclude("libevdev/libevdev.h");
@cInclude("libevdev/libevdev-uinput.h");
@cInclude("errno.h"); @cInclude("errno.h");
}); });
const CapsLockDown = c.input_event{ .type = c.EV_KEY, .code = c.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 = c.input_event{ .type = c.EV_KEY, .code = c.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 = 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 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 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 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 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 { 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: *c.input_event) !void { fn inputDeviceOpenAndGrab(dev_name: []const u8) !?*c.libevdev {
// event.* = try std.io.getStdIn().reader().readStruct(@TypeOf(event.*)); const dev_fd = try std.fs.openFileAbsolute(dev_name, .{});
//} const dev = c.libevdev_new();
if (c.libevdev_set_fd(dev, dev_fd.handle) < 0) {
fn event_write(event: *const c.input_event) !void { return error.libevdevCreateFail;
try std.io.getStdOut().writer().writeStruct(event.*); }
if (c.libevdev_grab(dev, c.LIBEVDEV_GRAB) < 0) {
return error.libevdevGrabFail;
}
return dev;
} }
fn write_esc() !void { fn uinputCreate(dev: *c.libevdev) !?*c.libevdev_uinput {
var uinput: *align(8) c.libevdev_uinput = undefined;
if (c.libevdev_uinput_create_from_device(@ptrCast(dev), c.LIBEVDEV_UINPUT_OPEN_MANAGED, @ptrCast(&uinput)) < 0) {
return error.libevdevUinputCreateFail;
}
return uinput;
}
fn uinputWrite(uinput_dev: *c.libevdev_uinput, event: *const c.input_event) !void {
if (c.libevdev_uinput_write_event(@ptrCast(uinput_dev), event.type, event.code, event.value) < 0) {
return error.writeFailed;
}
}
fn uinputWriteKey(uinput_dev: *c.libevdev_uinput, key: u16) !void {
const pressKey = c.input_event{ .type = c.EV_KEY, .code = key, .value = 1, .time = undefined };
const releaseKey = c.input_event{ .type = c.EV_KEY, .code = key, .value = 0, .time = undefined };
const sync = c.input_event{ .type = c.EV_SYN, .code = c.SYN_REPORT, .value = 0, .time = undefined };
std.time.sleep(20000); std.time.sleep(20000);
try event_write(&EscDown); try uinputWrite(uinput_dev, &pressKey);
try event_write(&Syn); try uinputWrite(uinput_dev, &sync);
std.time.sleep(20000); std.time.sleep(20000);
try event_write(&EscUp); try uinputWrite(uinput_dev, &releaseKey);
} }
fn device_open() !void {}
pub fn main() !void { pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator(); const allocator = gpa.allocator();
@ -49,17 +66,8 @@ pub fn main() !void {
std.os.exit(1); std.os.exit(1);
} }
const dev_name = args[1]; const dev_name = args[1];
var dev_fd = try std.fs.openFileAbsolute(dev_name, .{}); const dev = try inputDeviceOpenAndGrab(dev_name);
const uinput_dev = try uinputCreate(dev.?);
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;
@ -82,12 +90,12 @@ pub fn main() !void {
break :outer; break :outer;
} }
if (event.type == c.EV_MSC and event.type == c.MSC_SCAN) { if (event.type == c.EV_MSC and event.code == c.MSC_SCAN) {
continue :outer; continue :outer;
} }
if (event.type != c.EV_KEY) { if (event.type != c.EV_KEY) {
try event_write(&event); try uinputWrite(uinput_dev.?, &event);
continue :outer; continue :outer;
} }
@ -100,16 +108,16 @@ pub fn main() !void {
event.code = c.KEY_LEFTMETA; event.code = c.KEY_LEFTMETA;
} }
try event_write(&event); try uinputWrite(uinput_dev.?, &event);
if (write_esc_lshift) { if (write_esc_lshift) {
write_esc_lshift = false; write_esc_lshift = false;
try write_esc(); try uinputWriteKey(uinput_dev.?, c.KEY_ESC);
} }
if (write_esc_rshift) { if (write_esc_rshift) {
write_esc_rshift = false; write_esc_rshift = false;
try write_esc(); try uinputWriteKey(uinput_dev.?, c.KEY_ESC);
} }
} }
} }