Monorepo for Aesthetic.Computer
aesthetic.computer
1#ifndef AC_INPUT_H
2#define AC_INPUT_H
3
4#include <linux/input.h>
5#ifdef USE_WAYLAND
6#include <wayland-client.h>
7#endif
8
9#define MAX_INPUT_DEVICES 24
10#define MAX_HIDRAW_DEVICES 4
11#define MAX_EVENTS_PER_FRAME 64
12
13// NuPhy Air60 HE vendor ID
14#define NUPHY_VENDOR_ID 0x19f5
15
16// AC event types
17typedef enum {
18 AC_EVENT_NONE = 0,
19 AC_EVENT_KEYBOARD_DOWN,
20 AC_EVENT_KEYBOARD_UP,
21 AC_EVENT_TOUCH,
22 AC_EVENT_DRAW,
23 AC_EVENT_LIFT,
24 AC_EVENT_REFRAMED,
25} ACEventType;
26
27typedef struct {
28 ACEventType type;
29 int x, y; // Pointer coordinates
30 int key_code; // Linux key code
31 char key_name[32]; // AC key name ("a", "space", "arrowup", etc.)
32 int repeat; // Key repeat flag
33 float pressure; // 0.0-1.0 analog pressure (1.0 = full press, NuPhy HE)
34} ACEvent;
35
36// Per-key analog pressure state (for NuPhy HE)
37#define MAX_ANALOG_KEYS 128
38typedef struct {
39 int active; // Is this key currently pressed via analog?
40 int releasing; // Set when raw_pressure==0, release decay active
41 float pressure; // Current smoothed pressure 0.0-1.0
42 float target; // Last raw pressure target (NuPhy stops sending when stable)
43 float raw_accum; // Accumulated raw pressure this poll (for averaging)
44 int raw_count; // Number of HID reports this poll cycle
45 int key_code; // Linux keycode equivalent
46} ACAnalogKey;
47
48typedef struct {
49 int fds[MAX_INPUT_DEVICES];
50 int fd_is_analog[MAX_INPUT_DEVICES]; // Set if this evdev belongs to an analog keyboard
51 int count;
52 int pointer_x, pointer_y;
53 int pointer_down;
54 int delta_x, delta_y; // Per-frame pointer delta
55
56 // Trackpad absolute→relative conversion (BCM5974 etc.)
57 int abs_prev_x, abs_prev_y; // Previous absolute position (INT_MIN = not set)
58 int abs_x_min, abs_x_max; // Axis ranges from EVIOCGABS
59 int abs_y_min, abs_y_max;
60 int abs_x_res, abs_y_res; // Resolution (units/mm), 0 = unknown
61 int fd_is_trackpad[MAX_INPUT_DEVICES]; // This evdev is an abs trackpad
62
63 // HID raw devices (for analog keyboards like NuPhy HE)
64 int hidraw_fds[MAX_HIDRAW_DEVICES];
65 int hidraw_count;
66
67 // Per-key analog pressure tracking
68 ACAnalogKey analog_keys[MAX_ANALOG_KEYS];
69 int has_analog; // Set if an analog keyboard is detected
70 int hotplug_counter; // Polls since last hidraw scan
71 double last_poll_time; // Monotonic time of last poll (seconds)
72 int evdev_rescan_done; // Set after late evdev rescan
73 int evdev_rescan_counter; // Frame counter for late rescan
74
75 // Event queue for current frame
76 ACEvent events[MAX_EVENTS_PER_FRAME];
77 int event_count;
78
79 // Screen dimensions for touch scaling
80 int screen_w, screen_h;
81 int scale; // Display-to-piece scale factor (e.g. 3)
82
83 // Tablet mode (lid folded back on convertible laptops)
84 int tablet_mode; // 0 = laptop, 1 = tablet (from EV_SW or sysfs)
85
86#ifdef USE_WAYLAND
87 // Wayland input state
88 int is_wayland; // 1 if using Wayland input instead of evdev
89 void *wayland_display; // ACWaylandDisplay* — for event dispatch
90 // Key repeat state (Wayland doesn't send EV_KEY value=2)
91 int repeat_rate; // keys per second (from compositor)
92 int repeat_delay; // ms before repeat starts
93 int repeat_key; // currently repeating key (-1 if none)
94 double repeat_next; // monotonic time of next repeat event
95 double repeat_start; // when repeat was armed
96#endif
97} ACInput;
98
99ACInput *input_init(int screen_w, int screen_h, int scale);
100void input_poll(ACInput *input);
101void input_destroy(ACInput *input);
102
103#ifdef USE_WAYLAND
104// Initialize Wayland input — binds keyboard/pointer/touch from seat
105// Call after wayland_display_init() returns successfully
106struct ACWaylandDisplay;
107ACInput *input_init_wayland(void *wayland_display, int screen_w, int screen_h, int scale);
108#endif
109
110// Map Linux keycode to AC key name
111const char *input_key_name(int code);
112
113#endif