Guest User

Untitled

a guest
Mar 23rd, 2026
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. const std = @import("std");
  2. const linux = std.os.linux;
  3. const posix = std.posix;
  4.  
  5. const THRESHOLD_US: i64 = 70000;
  6.  
  7. const EVIOCGRAB: u32 = 0x40044590;
  8. const UI_SET_EVBIT: u32 = 0x40045564;
  9. const UI_SET_KEYBIT: u32 = 0x40045565;
  10. const UI_DEV_SETUP: u32 = 0x405c5503;
  11. const UI_DEV_CREATE: u32 = 0x5501;
  12. const UI_DEV_DESTROY: u32 = 0x5502;
  13.  
  14. const EV_SYN: u16 = 0;
  15. const EV_KEY: u16 = 1;
  16. const KEY_MAX: u32 = 767;
  17.  
  18. const KEY_BACKSPACE: u16 = 14;
  19. const KEY_W: u16 = 17;
  20. const KEY_E: u16 = 18;
  21. const KEY_R: u16 = 19;
  22. const KEY_S: u16 = 31;
  23. const KEY_N: u16 = 49;
  24. const KEY_C: u16 = 46;
  25. const KEY_SPACE: u16 = 57;
  26.  
  27. const PROBLEM_KEYS = [_]u16{ KEY_BACKSPACE, KEY_W, KEY_E, KEY_R, KEY_S, KEY_N, KEY_C, KEY_SPACE };
  28. const NUM_KEYS = PROBLEM_KEYS.len;
  29.  
  30. const InputEvent = extern struct {
  31.     sec: u64,
  32.     usec: u64,
  33.     type: u16,
  34.     code: u16,
  35.     value: i32,
  36. };
  37.  
  38. const UinputId = extern struct {
  39.     bustype: u16,
  40.     vendor: u16,
  41.     product: u16,
  42.     version: u16,
  43. };
  44.  
  45. const UinputSetup = extern struct {
  46.     id: UinputId,
  47.     name: [80]u8,
  48.     ff_effects_max: u32,
  49. };
  50.  
  51. const BUS_USB: u16 = 0x03;
  52.  
  53. pub fn main() !void {
  54.     var args = std.process.args();
  55.     _ = args.next(); // skip argv[0]
  56.     const dev_path = args.next() orelse {
  57.         _ = linux.write(2, "Usage: double-click-fix /dev/input/eventX\n", 42);
  58.         return error.BadArgs;
  59.     };
  60.  
  61.     const fd = @as(i32, @intCast(linux.open(dev_path.ptr, .{ .ACCMODE = .RDONLY }, 0)));
  62.     if (fd < 0) return error.OpenFailed;
  63.  
  64.     if (@as(isize, @bitCast(linux.ioctl(fd, EVIOCGRAB, 1))) < 0) return error.GrabFailed;
  65.  
  66.     const ui = @as(i32, @intCast(linux.open("/dev/uinput", .{ .ACCMODE = .WRONLY, .NONBLOCK = true }, 0)));
  67.     if (ui < 0) return error.UinputFailed;
  68.  
  69.     _ = linux.ioctl(ui, UI_SET_EVBIT, EV_KEY);
  70.     _ = linux.ioctl(ui, UI_SET_EVBIT, EV_SYN);
  71.     var k: u32 = 0;
  72.     while (k < KEY_MAX) : (k += 1) _ = linux.ioctl(ui, UI_SET_KEYBIT, k);
  73.  
  74.     var setup = std.mem.zeroes(UinputSetup);
  75.     setup.id.bustype = BUS_USB;
  76.     const dev_name = "double-click-fix";
  77.     @memcpy(setup.name[0..dev_name.len], dev_name);
  78.     _ = linux.ioctl(ui, UI_DEV_SETUP, @intFromPtr(&setup));
  79.     _ = linux.ioctl(ui, UI_DEV_CREATE, 0);
  80.  
  81.     var last_up = [_]i64{0} ** NUM_KEYS;
  82.     var pressed = [_]bool{false} ** NUM_KEYS;
  83.  
  84.     var e: InputEvent = undefined;
  85.     while (linux.read(fd, @ptrCast(&e), @sizeOf(InputEvent)) == @sizeOf(InputEvent)) {
  86.         if (e.type == EV_KEY) {
  87.             var idx: isize = -1;
  88.             for (PROBLEM_KEYS, 0..) |key, i| {
  89.                 if (e.code == key) { idx = @intCast(i); break; }
  90.             }
  91.             if (idx >= 0) {
  92.                 const i: usize = @intCast(idx);
  93.                 const now: i64 = @as(i64, @intCast(e.sec)) * 1_000_000 + @as(i64, @intCast(e.usec));
  94.                 if (e.value == 0) {
  95.                     if (!pressed[i]) continue;
  96.                     last_up[i] = now;
  97.                     pressed[i] = false;
  98.                 } else if (e.value == 1) {
  99.                     if (last_up[i] != 0 and now - last_up[i] < THRESHOLD_US) continue;
  100.                     pressed[i] = true;
  101.                 } else if (e.value == 2) {
  102.                     if (!pressed[i]) continue;
  103.                 }
  104.             }
  105.         }
  106.         _ = linux.write(ui, @ptrCast(&e), @sizeOf(InputEvent));
  107.     }
  108.  
  109.     _ = linux.ioctl(ui, UI_DEV_DESTROY, 0);
  110.     _ = linux.close(ui);
  111.     _ = linux.close(fd);
  112. }
Advertisement
Add Comment
Please, Sign In to add comment