From 373403d3c4735fe7d0e7f7d097f8e89ec92fdc46 Mon Sep 17 00:00:00 2001
From: haithium <128622475+haithium@users.noreply.github.com>
Date: Thu, 18 Jun 2026 19:07:23 +0000
Subject: [PATCH] docs: generate docs
---
docs/api/device.md | 227 ++++++------
docs/api/devices.md | 67 ++--
docs/api/events.md | 89 +++--
docs/api/selector.md | 152 ++++----
docs/api/uinput.md | 165 +++++----
docs/types.md | 822 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 1214 insertions(+), 308 deletions(-)
create mode 100644 docs/types.md
diff --git a/docs/api/device.md b/docs/api/device.md
index 10a3b64..b404c1b 100644
--- a/docs/api/device.md
+++ b/docs/api/device.md
@@ -1,66 +1,78 @@
---
title: "device"
-description: "One Linux input event returned by `Device:read()`."
+description: "Query and monitor physical Linux input devices."
---
-One Linux input event returned by `Device:read()`.
+Query and monitor physical Linux input devices.
+
+## Usage
+
+```lua
+local evdev = require "evdev"
+local Device = evdev.device.open
+
+-- Open an input device (e.g., event0)
+local dev = assert(Device("/dev/input/event0"))
+print("Opened device: " .. dev.name)
+
+-- Process events in a loop
+for ev in dev:events() do
+ if evdev.events.is_press(ev) then
+ print("Key Pressed! Code: " .. ev.code)
+ end
+end
+```
## Functions
-| Function | Description |
-| --------------------------------------------- | --------------------------------------------------------------------- |
-| [`close()`](#fn-close) | Close the device. |
-| [`events()`](#fn-events) | Return an iterator that waits for and yields input events one by one. |
-| [`fd()`](#fn-fd) | Return the underlying Linux file descriptor. |
-| [`flush()`](#fn-flush) | Drain queued events and return how many were discarded. |
-| [`get_repeat()`](#fn-get-repeat) | Return the current auto-repeat delay and period in milliseconds. |
-| [`grab()`](#fn-grab) | Take exclusive control of the input device. |
-| [`is_device(value)`](#fn-is-device) | Return whether a value is an `evdev.Device` instance. |
-| [`is_open()`](#fn-is-open) | Return whether this device handle still has an open file descriptor. |
-| [`open(path)`](#fn-open) | Open an input device by path. |
-| [`poll()`](#fn-poll) | Wait in the kernel until this device has input available. |
-| [`read()`](#fn-read) | Read one input event. Returns `nil` when no event is queued. |
-| [`set_repeat(delay, period)`](#fn-set-repeat) | Set the auto-repeat delay and period in milliseconds. |
-| [`ungrab()`](#fn-ungrab) | Release exclusive control of the input device. |
-
-
-
-### `close()`
+| Function | Description |
+| ----------------------------- | --------------------------------------------------------------------- |
+| [`close()`] | Close the device. |
+| [`events()`] | Return an iterator that waits for and yields input events one by one. |
+| [`fd()`] | Return the underlying Linux file descriptor. |
+| [`flush()`] | Drain queued events and return how many were discarded. |
+| [`get_repeat()`] | Return the current auto-repeat delay and period in milliseconds. |
+| [`grab()`] | Take exclusive control of the input device. |
+| [`is_device(value)`] | Return whether a value is an [`evdev.Device`] instance. |
+| [`is_open()`] | Return whether this device handle still has an open file descriptor. |
+| [`open(path)`] | Open an input device by path. |
+| [`poll()`] | Wait in the kernel until this device has input available. |
+| [`read()`] | Read one input event. Returns `nil` when no event is queued. |
+| [`set_repeat(delay, period)`] | Set the auto-repeat delay and period in milliseconds. |
+| [`ungrab()`] | Release exclusive control of the input device. |
+
+### `close()` {#close}
Close the device.
-**Return**:
+**Returns**:
- `ok` (`boolean`): `true` when the device closes successfully.
-- `err` (`string?`): Error message on failure.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
print(dev:is_open()) --> true
dev:close()
print(dev:is_open()) --> false
```
-
+---
-### `events()`
+### `events()` {#events}
Return an iterator that waits for and yields input events one by one.
-**Return**:
+**Returns**:
-- `evdev.event?` (`fun():`)
+- **value** (`fun():(ev?: `[`evdev.event`]`)`)
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
for e in dev:events() do
if e.type == ecodes.EV_KEY then
print(e.code, e.value)
@@ -68,46 +80,42 @@ for e in dev:events() do
end
```
-
+---
-### `fd()`
+### `fd()` {#fd}
Return the underlying Linux file descriptor.
-**Return**:
+**Returns**:
-- `fd` (`evdev.fd?`): Linux file descriptor.
+- `fd?` ([`evdev.fd`]): Linux file descriptor.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
local fd = dev:fd()
print(fd)
```
-
+---
-### `flush()`
+### `flush()` {#flush}
Drain queued events and return how many were discarded.
This is useful after grabbing a device when you want to ignore any stale events
that were already queued.
-**Return**:
+**Returns**:
-- `count` (`integer?`): Number of discarded events.
-- `err` (`string?`): Error message on failure.
+- `count?` (`integer`): Number of discarded events.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
assert(dev:grab())
-- Move the mouse or press keys during the sleep.
@@ -115,59 +123,56 @@ local dropped = assert(dev:flush())
print("discarded", dropped, "stale events")
```
-
+---
-### `get_repeat()`
+### `get_repeat()` {#get-repeat}
Return the current auto-repeat delay and period in milliseconds.
-**Return**:
+**Returns**:
-- `delay` (`integer?`): Initial delay before repeating (milliseconds).
-- `period` (`integer?`): Interval between repeats (milliseconds).
-- `err` (`string?`): Error message on failure.
+- `delay?` (`integer`): Initial delay before repeating (milliseconds).
+- `period?` (`integer`): Interval between repeats (milliseconds).
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
local delay, period, err = dev:get_repeat()
assert(delay, err)
print(delay, period)
```
-
+---
-### `grab()`
+### `grab()` {#grab}
Take exclusive control of the input device.
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when the device is grabbed successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when the device is grabbed successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
assert(dev:grab())
```
-
+---
-### `is_device(value)`
+### `is_device(value)` {#is-device}
-Return whether a value is an `evdev.Device` instance.
+Return whether a value is an [`evdev.Device`] instance.
**Parameters**:
- `value` (`any`)
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -182,69 +187,64 @@ print(is_device(dev)) --> true
print(is_device({})) --> false
```
-
+---
-### `is_open()`
+### `is_open()` {#is-open}
Return whether this device handle still has an open file descriptor.
-**Return**:
+**Returns**:
- `isOpen` (`boolean`): `true` when the device is still open.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
if dev:is_open()
then dev:close()
end
```
-
+---
-### `open(path)`
+### `open(path)` {#open}
Open an input device by path.
**Parameters**:
-- `path` (`evdev.path`)
+- `path` ([`evdev.path`])
-**Return**:
+**Returns**:
-- `dev` (`evdev.Device?`): Open input device.
-- `err` (`string?`): Error message on failure.
+- `dev?` ([`evdev.Device`]): Open input device.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
-local dev = assert(Device("/dev/input/eventX"))
+local dev = assert(evdev.device.open("/dev/input/eventX"))
```
-
+---
-### `poll()`
+### `poll()` {#poll}
Wait in the kernel until this device has input available.
-This does not spin the CPU. It returns when `read()` can fetch at least one
-queued event.
+This does not spin the CPU. It returns when [`evdev.device.read()`] can fetch at
+least one queued event.
-**Return**:
+**Returns**:
-- `ready` (`boolean?`): `true` when input is ready to read.
-- `err` (`string?`): Error message on failure.
+- `ready?` (`boolean`): `true` when input is ready to read.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local ecodes = evdev.ecodes
-
local dev = assert(Device("/dev/input/eventX"))
-- This is the manual form of `dev:events()`.
@@ -258,23 +258,21 @@ while true do
end
```
-
+---
-### `read()`
+### `read()` {#read}
Read one input event. Returns `nil` when no event is queued.
-**Return**:
+**Returns**:
-- `event` (`evdev.event?`): Next queued input event.
-- `err` (`string?`): Error message on failure.
+- `event?` ([`evdev.event`]): Next queued input event.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
-- This is the manual form of `dev:events()`.
while true do
if assert(dev:poll()) then
@@ -286,9 +284,9 @@ while true do
end
```
-
+---
-### `set_repeat(delay, period)`
+### `set_repeat(delay, period)` {#set-repeat}
Set the auto-repeat delay and period in milliseconds.
@@ -297,18 +295,17 @@ Set the auto-repeat delay and period in milliseconds.
- `delay` (`integer`): Initial delay before repeating (milliseconds).
- `period` (`integer`): Interval between repeats (milliseconds).
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when the repeat settings are updated successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when the repeat settings are updated successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
-
local delay, period, err = dev:get_repeat()
+
assert(delay, err)
print(delay, period)
@@ -316,22 +313,44 @@ assert(dev:set_repeat(300, 40))
print(dev:get_repeat())
```
-
+---
-### `ungrab()`
+### `ungrab()` {#ungrab}
Release exclusive control of the input device.
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when the grab is released successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when the grab is released successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local Device = evdev.device.open
local dev = assert(Device("/dev/input/eventX"))
assert(dev:grab())
assert(dev:ungrab())
```
+
+
+
+[`close()`]: #close
+[`evdev.Device`]: /evdev/api/device
+[`evdev.device.read()`]: /evdev/api/device#read
+[`evdev.event`]: /evdev/types#evdev-event
+[`evdev.fd`]: /evdev/types#evdev-fd
+[`evdev.path`]: /evdev/types#evdev-path
+[`events()`]: #events
+[`fd()`]: #fd
+[`flush()`]: #flush
+[`get_repeat()`]: #get-repeat
+[`grab()`]: #grab
+[`is_device(value)`]: #is-device
+[`is_open()`]: #is-open
+[`open(path)`]: #open
+[`poll()`]: #poll
+[`read()`]: #read
+[`set_repeat(delay, period)`]: #set-repeat
+[`ungrab()`]: #ungrab
+
+
diff --git a/docs/api/devices.md b/docs/api/devices.md
index 2fbff40..b20bd47 100644
--- a/docs/api/devices.md
+++ b/docs/api/devices.md
@@ -5,6 +5,8 @@ description: "Input device discovery helpers."
Input device discovery helpers.
+## Usage
+
```lua
local devices = assert(evdev.devices.list_devices())
print(#devices)
@@ -12,27 +14,25 @@ print(#devices)
## Functions
-| Function | Description |
-| -------------------------------------- | --------------------------------------------------------------------------- |
-| [`device_info(path)`](#fn-device-info) | Read metadata for one input device by path. |
-| [`find(query)`](#fn-find) | Return the first discovered input device matching a path or a device name. |
-| [`find_all(query)`](#fn-find-all) | Return all discovered input devices matching a path, alias, or device name. |
-| [`list_devices()`](#fn-list-devices) | List evdev input devices under `/dev/input`. |
-
-
+| Function | Description |
+| --------------------- | --------------------------------------------------------------------------- |
+| [`device_info(path)`] | Read metadata for one input device by path. |
+| [`find(query)`] | Return the first discovered input device matching a path or a device name. |
+| [`find_all(query)`] | Return all discovered input devices matching a path, alias, or device name. |
+| [`list_devices()`] | List evdev input devices under `/dev/input`. |
-### `device_info(path)`
+### `device_info(path)` {#device-info}
Read metadata for one input device by path.
**Parameters**:
-- `path` (`evdev.path`)
+- `path` ([`evdev.path`])
-**Return**:
+**Returns**:
-- `info` (`evdev.deviceInfo?`)
-- `err` (`string?`)
+- `info?` ([`evdev.deviceInfo`])
+- `err?` (`string`)
**Example**:
@@ -41,9 +41,9 @@ local dev = assert(evdev.devices.device_info("/dev/input/event3"))
print(dev.name)
```
-
+---
-### `find(query)`
+### `find(query)` {#find}
Return the first discovered input device matching a path or a device name.
@@ -52,10 +52,10 @@ Return the first discovered input device matching a path or a device name.
- `query` (`string`): Exact device path, by-id path, by-path path, or device
name.
-**Return**:
+**Returns**:
-- `dev` (`evdev.deviceInfo?`)
-- `err` (`string?`)
+- `dev?` ([`evdev.deviceInfo`])
+- `err?` (`string`)
**Example**:
@@ -73,9 +73,9 @@ print(by_id_alias and by_id_alias.path)
print(by_name and by_name.path)
```
-
+---
-### `find_all(query)`
+### `find_all(query)` {#find-all}
Return all discovered input devices matching a path, alias, or device name.
@@ -84,10 +84,10 @@ Return all discovered input devices matching a path, alias, or device name.
- `query` (`string`): Exact device path, by-id path, by-path path, or device
name.
-**Return**:
+**Returns**:
-- `devs` (`evdev.deviceInfo[]?`)
-- `err` (`string?`)
+- `devs?` ([`evdev.deviceInfo`]`[]`)
+- `err?` (`string`)
**Example**:
@@ -105,16 +105,16 @@ print(#by_id_alias)
print(#by_name)
```
-
+---
-### `list_devices()`
+### `list_devices()` {#list-devices}
List evdev input devices under `/dev/input`.
-**Return**:
+**Returns**:
-- `devs` (`evdev.deviceInfo[]?`)
-- `err` (`string?`)
+- `devs?` ([`evdev.deviceInfo`]`[]`)
+- `err?` (`string`)
**Example**:
@@ -124,3 +124,14 @@ for _, dev in ipairs(devs) do
print(dev.path, dev.name)
end
```
+
+
+
+[`device_info(path)`]: #device-info
+[`evdev.deviceInfo`]: /evdev/types#evdev-deviceinfo
+[`evdev.path`]: /evdev/types#evdev-path
+[`find(query)`]: #find
+[`find_all(query)`]: #find-all
+[`list_devices()`]: #list-devices
+
+
diff --git a/docs/api/events.md b/docs/api/events.md
index 19c3dc4..1afd88c 100644
--- a/docs/api/events.md
+++ b/docs/api/events.md
@@ -5,6 +5,8 @@ description: "Event value constants and event predicates."
Event value constants and event predicates.
+## Usage
+
```lua
local e = {
type = evdev.ecodes.EV_KEY,
@@ -18,27 +20,25 @@ print(evdev.events.is_repeat(e)) --> false
## Functions
-| Function | Description |
-| ------------------------------------- | ------------------------------------------------ |
-| [`is_abs(event)`](#fn-is-abs) | Return whether an event has type `EV_ABS`. |
-| [`is_key(event)`](#fn-is-key) | Return whether an event has type `EV_KEY`. |
-| [`is_press(event)`](#fn-is-press) | Return whether an event is a key/button press. |
-| [`is_rel(event)`](#fn-is-rel) | Return whether an event has type `EV_REL`. |
-| [`is_release(event)`](#fn-is-release) | Return whether an event is a key/button release. |
-| [`is_repeat(event)`](#fn-is-repeat) | Return whether an event is a key repeat. |
-| [`is_syn(event)`](#fn-is-syn) | Return whether an event has type `EV_SYN`. |
-
-
+| Function | Description |
+| --------------------- | ------------------------------------------------ |
+| [`is_abs(event)`] | Return whether an event has type `EV_ABS`. |
+| [`is_key(event)`] | Return whether an event has type `EV_KEY`. |
+| [`is_press(event)`] | Return whether an event is a key/button press. |
+| [`is_rel(event)`] | Return whether an event has type `EV_REL`. |
+| [`is_release(event)`] | Return whether an event is a key/button release. |
+| [`is_repeat(event)`] | Return whether an event is a key repeat. |
+| [`is_syn(event)`] | Return whether an event has type `EV_SYN`. |
-### `is_abs(event)`
+### `is_abs(event)` {#is-abs}
Return whether an event has type `EV_ABS`.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -49,17 +49,17 @@ local e = { type = evdev.ecodes.EV_ABS }
print(evdev.events.is_abs(e)) --> true
```
-
+---
-### `is_key(event)`
+### `is_key(event)` {#is-key}
Return whether an event has type `EV_KEY`.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -70,17 +70,17 @@ local e = { type = evdev.ecodes.EV_KEY }
print(evdev.events.is_key(e)) --> true
```
-
+---
-### `is_press(event)`
+### `is_press(event)` {#is-press}
Return whether an event is a key/button press.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -91,17 +91,17 @@ local e = { type = evdev.ecodes.EV_KEY, value = evdev.events.PRESS }
print(evdev.events.is_press(e)) --> true
```
-
+---
-### `is_rel(event)`
+### `is_rel(event)` {#is-rel}
Return whether an event has type `EV_REL`.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -112,17 +112,17 @@ local e = { type = evdev.ecodes.EV_REL }
print(evdev.events.is_rel(e)) --> true
```
-
+---
-### `is_release(event)`
+### `is_release(event)` {#is-release}
Return whether an event is a key/button release.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -133,17 +133,17 @@ local e = { type = evdev.ecodes.EV_KEY, value = evdev.events.RELEASE }
print(evdev.events.is_release(e)) --> true
```
-
+---
-### `is_repeat(event)`
+### `is_repeat(event)` {#is-repeat}
Return whether an event is a key repeat.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -154,17 +154,17 @@ local e = { type = evdev.ecodes.EV_KEY, value = evdev.events.REPEAT }
print(evdev.events.is_repeat(e)) --> true
```
-
+---
-### `is_syn(event)`
+### `is_syn(event)` {#is-syn}
Return whether an event has type `EV_SYN`.
**Parameters**:
-- `event` (`evdev.event`)
+- `event` ([`evdev.event`])
-**Return**:
+**Returns**:
- **value** (`boolean`)
@@ -174,3 +174,16 @@ Return whether an event has type `EV_SYN`.
local e = { type = evdev.ecodes.EV_SYN }
print(evdev.events.is_syn(e)) --> true
```
+
+
+
+[`evdev.event`]: /evdev/types#evdev-event
+[`is_abs(event)`]: #is-abs
+[`is_key(event)`]: #is-key
+[`is_press(event)`]: #is-press
+[`is_rel(event)`]: #is-rel
+[`is_release(event)`]: #is-release
+[`is_repeat(event)`]: #is-repeat
+[`is_syn(event)`]: #is-syn
+
+
diff --git a/docs/api/selector.md b/docs/api/selector.md
index ec5a8bc..44fb96f 100644
--- a/docs/api/selector.md
+++ b/docs/api/selector.md
@@ -1,139 +1,138 @@
---
title: "selector"
-description: "Selector for polling and reading from multiple devices."
+description: "Monitor and read events from multiple input devices."
---
-Selector for polling and reading from multiple devices.
+Monitor and read events from multiple input devices.
-## Functions
+## Usage
-| Function | Description |
-| ------------------------------ | -------------------------------------------------------------- |
-| [`add(device)`](#fn-add) | Add a device to this selector. |
-| [`clear()`](#fn-clear) | Remove all devices from this selector. |
-| [`events()`](#fn-events) | Return an iterator that yields events from registered devices. |
-| [`new(devices?)`](#fn-new) | Create a selector from an optional list of devices. |
-| [`poll()`](#fn-poll) | Wait until at least one registered device has input available. |
-| [`remove(device)`](#fn-remove) | Remove a device from this selector. |
+```lua
+local evdev = require "evdev"
-
+local Device = evdev.device.open
+local Selector = evdev.selector.new
-### `add(device)`
+local dev1 = assert(Device("/dev/input/eventX"))
+local dev2 = assert(Device("/dev/input/eventY"))
+local sel = Selector({ dev1, dev2 })
-Add a device to this selector.
+for dev, ev in sel:events() do
+ print(dev.name, ev.code, ev.value)
+end
+```
+
+## Functions
+
+| Function | Description |
+| ------------------ | -------------------------------------------------------------- |
+| [`new(devices?)`] | Create a selector from an optional list of devices. |
+| [`add(device)`] | Add a device to this selector. |
+| [`clear()`] | Remove all devices from this selector. |
+| [`events()`] | Return an iterator that yields events from registered devices. |
+| [`poll()`] | Wait until at least one registered device has input available. |
+| [`remove(device)`] | Remove a device from this selector. |
+
+### `new(devices?)` {#new}
+
+Create a selector from an optional list of devices.
**Parameters**:
-- `device` (`evdev.Device`)
+- `devices?` ([`evdev.Device`]`[]`)
-**Return**:
+**Returns**:
-- **value** (`self`)
+- **value** ([`evdev.Selector`])
**Example**:
```lua
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
-local sel = Selector({ kb1 })
-
-sel:add(kb2)
+local sel = Selector({ kb1, kb2 })
```
-
+---
-### `clear()`
+### `add(device)` {#add}
-Remove all devices from this selector.
+Add a device to this selector.
+
+**Parameters**:
-**Return**:
+- `device` ([`evdev.Device`])
+
+**Returns**:
- **value** (`self`)
**Example**:
```lua
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
-local sel = Selector({ kb1, kb2 })
+local sel = Selector({ kb1 })
-sel:clear()
+sel:add(kb2)
```
-
+---
-### `events()`
+### `clear()` {#clear}
-Return an iterator that yields events from registered devices.
+Remove all devices from this selector.
-**Return**:
+**Returns**:
-- `evdev.Device?,` (`fun():`): evdev.event?
+- **value** (`self`)
**Example**:
```lua
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
local sel = Selector({ kb1, kb2 })
-for dev, e in sel:events() do
- print(dev.name, e.code, e.value)
-end
+sel:clear()
```
-
-
-### `new(devices?)`
-
-Create a selector from an optional list of devices.
+---
-**Parameters**:
+### `events()` {#events}
-- `devices?` (`evdev.Device[]`)
+Return an iterator that yields events from registered devices.
-**Return**:
+**Returns**:
-- **value** (`evdev.Selector`)
+- **value** (`fun(): (dev?: `[`evdev.Device`]`, ev?: `[`evdev.event`]`)`)
**Example**:
```lua
-local evdev = require "evdev"
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
local sel = Selector({ kb1, kb2 })
+
+for dev, e in sel:events() do
+ print(dev.name, e.code, e.value)
+end
```
-
+---
-### `poll()`
+### `poll()` {#poll}
Wait until at least one registered device has input available.
-**Return**:
+**Returns**:
-- `devs` (`evdev.Device[]?`)
-- `err` (`string?`)
+- `devs?` ([`evdev.Device`]`[]`)
+- `err?` (`string`)
**Example**:
```lua
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
local sel = Selector({ kb1, kb2 })
@@ -143,29 +142,40 @@ for _, dev in ipairs(assert(sel:poll())) do
end
```
-
+---
-### `remove(device)`
+### `remove(device)` {#remove}
Remove a device from this selector.
**Parameters**:
-- `device` (`evdev.Device`)
+- `device` ([`evdev.Device`])
-**Return**:
+**Returns**:
- **value** (`self`)
**Example**:
```lua
-local Device = evdev.device.open
-local Selector = evdev.selector.new
-
local kb1 = assert(Device("/dev/input/event5"))
local kb2 = assert(Device("/dev/input/event10"))
local sel = Selector({ kb1, kb2 })
sel:remove(kb2)
```
+
+
+
+[`add(device)`]: #add
+[`clear()`]: #clear
+[`evdev.Device`]: /evdev/api/device
+[`evdev.Selector`]: /evdev/api/selector
+[`evdev.event`]: /evdev/types#evdev-event
+[`events()`]: #events
+[`new(devices?)`]: #new
+[`poll()`]: #poll
+[`remove(device)`]: #remove
+
+
diff --git a/docs/api/uinput.md b/docs/api/uinput.md
index 537aa13..90ce7ec 100644
--- a/docs/api/uinput.md
+++ b/docs/api/uinput.md
@@ -1,61 +1,81 @@
---
title: "uinput"
-description: "Configuration used to create a `/dev/uinput` virtual device."
+description: "Create and control virtual input devices using `/dev/uinput`."
---
-Configuration used to create a `/dev/uinput` virtual device.
+Create and control virtual input devices using `/dev/uinput`.
-## Functions
+## Usage
+
+```lua
+local evdev = require "evdev"
+
+local ecodes = evdev.ecodes
+local UInput = evdev.uinput.create
+
+-- Create a virtual keyboard device
+local ui = assert(UInput())
+print("Virtual device created at: " .. ui.path)
+
+-- Simulate typing Shift + A
+ui:emit(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
+ui:emit(ecodes.EV_KEY, ecodes.KEY_A, 1)
+ui:sync()
-| Function | Description |
-| --------------------------------------------- | ------------------------------------------------------------- |
-| [`close()`](#fn-close) | Destroy and close the virtual device. |
-| [`create(spec?)`](#fn-create) | Create a virtual input device. |
-| [`emit(type, code, value)`](#fn-emit) | Emit one raw input event. |
-| [`fd()`](#fn-fd) | Get the file descriptor of the virtual device. |
-| [`get_repeat()`](#fn-get-repeat) | Get the current keyboard repeat rate from the virtual device. |
-| [`is_open()`](#fn-is-open) | Return whether the virtual device is still open. |
-| [`set_repeat(delay, period)`](#fn-set-repeat) | Set the keyboard repeat rate on the virtual device. |
-| [`sync()`](#fn-sync) | Emit a `SYN_REPORT` event. |
+ui:emit(ecodes.EV_KEY, ecodes.KEY_A, 0)
+ui:emit(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)
+ui:sync()
-
+ui:close()
+```
+
+## Functions
-### `close()`
+| Function | Description |
+| ----------------------------- | ------------------------------------------------------------- |
+| [`close()`] | Destroy and close the virtual device. |
+| [`create(spec?)`] | Create a virtual input device. |
+| [`emit(type, code, value)`] | Emit one raw input event. |
+| [`fd()`] | Get the file descriptor of the virtual device. |
+| [`get_repeat()`] | Get the current keyboard repeat rate from the virtual device. |
+| [`is_open()`] | Return whether the virtual device is still open. |
+| [`set_repeat(delay, period)`] | Set the keyboard repeat rate on the virtual device. |
+| [`sync()`] | Emit a `SYN_REPORT` event. |
+
+### `close()` {#close}
Destroy and close the virtual device.
-**Return**:
+**Returns**:
- `ok` (`boolean`): `true` when the virtual device closes successfully.
-- `err` (`string?`): Error message on failure.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
ui:close()
```
-
+---
-### `create(spec?)`
+### `create(spec?)` {#create}
Create a virtual input device.
**Parameters**:
-- `spec?` (`evdev.uinputSpec`): Virtual device configuration.
+- `spec?` ([`evdev.uinputSpec`]): Virtual device configuration.
-**Return**:
+**Returns**:
-- `dev` (`evdev.UInput?`): Open virtual device.
-- `err` (`string?`): Error message on failure.
+- `dev?` ([`evdev.UInput`]): Open virtual device.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
ui:emit(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_A, 1)
@@ -65,28 +85,27 @@ ui:sync()
print(ui.path)
```
-
+---
-### `emit(type, code, value)`
+### `emit(type, code, value)` {#emit}
Emit one raw input event.
**Parameters**:
-- `type` (`evdev.ecodes.ev`): Event type to emit.
-- `code` (`evdev.ecodes.key|evdev.ecodes.btn|evdev.ecodes.rel`): Event code
- within the selected type.
-- `value` (`evdev.eventValue`): Event value to send.
+- `type` ([`evdev.ecodes.ev`]): Event type to emit.
+- `code` ([`evdev.ecodes.key`] | [`evdev.ecodes.btn`] | [`evdev.ecodes.rel`]):
+ Event code within the selected type.
+- `value` ([`evdev.eventValue`]): Event value to send.
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when the event is emitted successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when the event is emitted successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
local EV_KEY = evdev.ecodes.EV_KEY
@@ -100,71 +119,66 @@ ui:emit(EV_REL, evdev.ecodes.REL_Y, 10)
ui:sync()
```
-
+---
-### `fd()`
+### `fd()` {#fd}
Get the file descriptor of the virtual device.
-**Return**:
+**Returns**:
-- `fd` (`evdev.fd?`): Linux file descriptor.
+- `fd?` ([`evdev.fd`]): Linux file descriptor.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
print(ui:fd())
```
-
+---
-### `get_repeat()`
+### `get_repeat()` {#get-repeat}
Get the current keyboard repeat rate from the virtual device.
-**Return**:
+**Returns**:
-- `delay` (`integer?`): Repeat delay in milliseconds.
-- `period` (`integer?`): Repeat period in milliseconds.
-- `err` (`string?`): Error message on failure.
+- `delay?` (`integer`): Repeat delay in milliseconds.
+- `period?` (`integer`): Repeat period in milliseconds.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
-
local delay, period, err = ui:get_repeat()
assert(delay, err)
print(delay, period)
```
-
+---
-### `is_open()`
+### `is_open()` {#is-open}
Return whether the virtual device is still open.
-**Return**:
+**Returns**:
- `is_open` (`boolean`): `true` when the virtual device is still open.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
-
if ui:is_open() then
ui:close()
end
```
-
+---
-### `set_repeat(delay, period)`
+### `set_repeat(delay, period)` {#set-repeat}
Set the keyboard repeat rate on the virtual device.
@@ -173,40 +187,57 @@ Set the keyboard repeat rate on the virtual device.
- `delay` (`integer`): Delay in milliseconds before key repeat starts.
- `period` (`integer`): Period in milliseconds between repeated key events.
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when the repeat rate is set successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when the repeat rate is set successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
-
-- Set repeat delay to 500ms, repeat period to 50ms
ui:set_repeat(500, 50)
```
-
+---
-### `sync()`
+### `sync()` {#sync}
Emit a `SYN_REPORT` event.
Flush queued input events as one frame.
-**Return**:
+**Returns**:
-- `ok` (`true?`): `true` when `SYN_REPORT` is emitted successfully.
-- `err` (`string?`): Error message on failure.
+- `ok?` (`true`): `true` when `SYN_REPORT` is emitted successfully.
+- `err?` (`string`): Error message on failure.
**Example**:
```lua
-local UInput = evdev.uinput.create
local ui = assert(UInput())
-
ui:emit(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 0)
ui:sync()
```
+
+
+
+[`close()`]: #close
+[`create(spec?)`]: #create
+[`emit(type, code, value)`]: #emit
+[`evdev.UInput`]: /evdev/api/uinput
+[`evdev.ecodes.btn`]: /evdev/api/ecodes
+[`evdev.ecodes.ev`]: /evdev/api/ecodes
+[`evdev.ecodes.key`]: /evdev/api/ecodes
+[`evdev.ecodes.rel`]: /evdev/api/ecodes
+[`evdev.eventValue`]: /evdev/types#evdev-eventvalue
+[`evdev.fd`]: /evdev/types#evdev-fd
+[`evdev.uinputSpec`]: /evdev/types#evdev-uinputspec
+[`fd()`]: #fd
+[`get_repeat()`]: #get-repeat
+[`is_open()`]: #is-open
+[`set_repeat(delay, period)`]: #set-repeat
+[`sync()`]: #sync
+
+
diff --git a/docs/types.md b/docs/types.md
new file mode 100644
index 0000000..f193d62
--- /dev/null
+++ b/docs/types.md
@@ -0,0 +1,822 @@
+---
+title: "Types"
+description: "Types defined in the evdev module."
+---
+
+Types defined in the evdev module.
+
+## [`evdev.coreDevice`](https://github.com/BlueLua/evdev/blob/main/types/device.d.lua#L29-L43)
+
+Open and manage input devices.
+
+| Field | Type | Optional |
+| ------------ | ------------------------------------------------------------------- | -------- |
+| `close` | `fun(self): (ok:true?, err:string?)` | No |
+| `fd` | `fun(self): (fd:`[`evdev.fd`]`?, err:string?)` | No |
+| `flush` | `fun(self): (count:integer?, err:string?)` | No |
+| `get_repeat` | `fun(self): (delay:integer?, period:integer?, err:string?)` | No |
+| `grab` | `fun(self): (ok:true?, err:string?)` | No |
+| `is_open` | `fun(self): boolean` | No |
+| `poll` | `fun(self): (ready:boolean?, err:string?)` | No |
+| `read` | `fun(self): (event:`[`evdev.event`]`?, err:string?)` | No |
+| `set_repeat` | `fun(self, delay:integer, period:integer): (ok:true?, err:string?)` | No |
+| `ungrab` | `fun(self): (ok:true?, err:string?)` | No |
+
+## [`evdev.coreUInput`](https://github.com/BlueLua/evdev/blob/main/types/uinput.d.lua#L66-L77)
+
+Open virtual input device handle.
+
+| Field | Type | Optional |
+| ------------ | ------------------------------------------------------------------------------------------------------------ | -------- |
+| `close` | `fun(self): (ok:true?, err:string?)` | No |
+| `emit` | `fun(self, type:`[`evdev.ecodes.ev`]`, code:integer, value:`[`evdev.eventValue`]`): (ok:true?, err:string?)` | No |
+| `get_repeat` | `fun(self): (delay:integer?, period_or_err:(integer` \| `string)?)` | No |
+| `info` | `fun(self): (info:`[`evdev.deviceInfo`]`?, err:string?)` | No |
+| `is_open` | `fun(self): boolean` | No |
+| `set_repeat` | `fun(self, delay:integer, period:integer): (ok:true?, err:string?)` | No |
+| `sync` | `fun(self): (ok:true?, err:string?)` | No |
+
+## [`evdev.deviceInfo`](https://github.com/BlueLua/evdev/blob/main/types/device.d.lua#L14-L28)
+
+Input device metadata.
+
+| Field | Type | Optional | Description |
+| -------------- | ---------- | -------- | ----------------------------------------------------------- |
+| `bustype` | `integer` | No | Bus type from the kernel input ID. |
+| `id_aliases` | `string[]` | Yes | Symlink aliases under `/dev/input/by-id`, when available. |
+| `name` | `string` | Yes | Device name reported by the kernel. |
+| `path` | `string` | No | Device node path. |
+| `path_aliases` | `string[]` | Yes | Symlink aliases under `/dev/input/by-path`, when available. |
+| `phys` | `string` | Yes | Physical device path, when available. |
+| `product` | `integer` | No | Product ID from the kernel input ID. |
+| `uniq` | `string` | Yes | Unique identifier string, when available. |
+| `vendor` | `integer` | No | Vendor ID from the kernel input ID. |
+| `version` | `integer` | No | Hardware version from the kernel input ID. |
+
+## [`evdev.ecodes.btn`](https://github.com/BlueLua/evdev/blob/main/types/_enums.d.lua#L9-L134)
+
+| Name | Value |
+| --------------------- | ----- |
+| `BTN_0` | `256` |
+| `BTN_1` | `257` |
+| `BTN_2` | `258` |
+| `BTN_3` | `259` |
+| `BTN_4` | `260` |
+| `BTN_5` | `261` |
+| `BTN_6` | `262` |
+| `BTN_7` | `263` |
+| `BTN_8` | `264` |
+| `BTN_9` | `265` |
+| `BTN_A` | `304` |
+| `BTN_B` | `305` |
+| `BTN_BACK` | `278` |
+| `BTN_BASE` | `294` |
+| `BTN_BASE2` | `295` |
+| `BTN_BASE3` | `296` |
+| `BTN_BASE4` | `297` |
+| `BTN_BASE5` | `298` |
+| `BTN_BASE6` | `299` |
+| `BTN_C` | `306` |
+| `BTN_DEAD` | `303` |
+| `BTN_DIGI` | `320` |
+| `BTN_DPAD_DOWN` | `545` |
+| `BTN_DPAD_LEFT` | `546` |
+| `BTN_DPAD_RIGHT` | `547` |
+| `BTN_DPAD_UP` | `544` |
+| `BTN_EAST` | `305` |
+| `BTN_EXTRA` | `276` |
+| `BTN_FORWARD` | `277` |
+| `BTN_GAMEPAD` | `304` |
+| `BTN_GEAR_DOWN` | `336` |
+| `BTN_GEAR_UP` | `337` |
+| `BTN_GRIPL` | `548` |
+| `BTN_GRIPL2` | `550` |
+| `BTN_GRIPR` | `549` |
+| `BTN_GRIPR2` | `551` |
+| `BTN_JOYSTICK` | `288` |
+| `BTN_LEFT` | `272` |
+| `BTN_MIDDLE` | `274` |
+| `BTN_MISC` | `256` |
+| `BTN_MODE` | `316` |
+| `BTN_MOUSE` | `272` |
+| `BTN_NORTH` | `307` |
+| `BTN_PINKIE` | `293` |
+| `BTN_RIGHT` | `273` |
+| `BTN_SELECT` | `314` |
+| `BTN_SIDE` | `275` |
+| `BTN_SOUTH` | `304` |
+| `BTN_START` | `315` |
+| `BTN_STYLUS` | `331` |
+| `BTN_STYLUS2` | `332` |
+| `BTN_STYLUS3` | `329` |
+| `BTN_TASK` | `279` |
+| `BTN_THUMB` | `289` |
+| `BTN_THUMB2` | `290` |
+| `BTN_THUMBL` | `317` |
+| `BTN_THUMBR` | `318` |
+| `BTN_TL` | `310` |
+| `BTN_TL2` | `312` |
+| `BTN_TOOL_AIRBRUSH` | `324` |
+| `BTN_TOOL_BRUSH` | `322` |
+| `BTN_TOOL_DOUBLETAP` | `333` |
+| `BTN_TOOL_FINGER` | `325` |
+| `BTN_TOOL_LENS` | `327` |
+| `BTN_TOOL_MOUSE` | `326` |
+| `BTN_TOOL_PEN` | `320` |
+| `BTN_TOOL_PENCIL` | `323` |
+| `BTN_TOOL_QUADTAP` | `335` |
+| `BTN_TOOL_QUINTTAP` | `328` |
+| `BTN_TOOL_RUBBER` | `321` |
+| `BTN_TOOL_TRIPLETAP` | `334` |
+| `BTN_TOP` | `291` |
+| `BTN_TOP2` | `292` |
+| `BTN_TOUCH` | `330` |
+| `BTN_TR` | `311` |
+| `BTN_TR2` | `313` |
+| `BTN_TRIGGER` | `288` |
+| `BTN_TRIGGER_HAPPY` | `704` |
+| `BTN_TRIGGER_HAPPY1` | `704` |
+| `BTN_TRIGGER_HAPPY10` | `713` |
+| `BTN_TRIGGER_HAPPY11` | `714` |
+| `BTN_TRIGGER_HAPPY12` | `715` |
+| `BTN_TRIGGER_HAPPY13` | `716` |
+| `BTN_TRIGGER_HAPPY14` | `717` |
+| `BTN_TRIGGER_HAPPY15` | `718` |
+| `BTN_TRIGGER_HAPPY16` | `719` |
+| `BTN_TRIGGER_HAPPY17` | `720` |
+| `BTN_TRIGGER_HAPPY18` | `721` |
+| `BTN_TRIGGER_HAPPY19` | `722` |
+| `BTN_TRIGGER_HAPPY2` | `705` |
+| `BTN_TRIGGER_HAPPY20` | `723` |
+| `BTN_TRIGGER_HAPPY21` | `724` |
+| `BTN_TRIGGER_HAPPY22` | `725` |
+| `BTN_TRIGGER_HAPPY23` | `726` |
+| `BTN_TRIGGER_HAPPY24` | `727` |
+| `BTN_TRIGGER_HAPPY25` | `728` |
+| `BTN_TRIGGER_HAPPY26` | `729` |
+| `BTN_TRIGGER_HAPPY27` | `730` |
+| `BTN_TRIGGER_HAPPY28` | `731` |
+| `BTN_TRIGGER_HAPPY29` | `732` |
+| `BTN_TRIGGER_HAPPY3` | `706` |
+| `BTN_TRIGGER_HAPPY30` | `733` |
+| `BTN_TRIGGER_HAPPY31` | `734` |
+| `BTN_TRIGGER_HAPPY32` | `735` |
+| `BTN_TRIGGER_HAPPY33` | `736` |
+| `BTN_TRIGGER_HAPPY34` | `737` |
+| `BTN_TRIGGER_HAPPY35` | `738` |
+| `BTN_TRIGGER_HAPPY36` | `739` |
+| `BTN_TRIGGER_HAPPY37` | `740` |
+| `BTN_TRIGGER_HAPPY38` | `741` |
+| `BTN_TRIGGER_HAPPY39` | `742` |
+| `BTN_TRIGGER_HAPPY4` | `707` |
+| `BTN_TRIGGER_HAPPY40` | `743` |
+| `BTN_TRIGGER_HAPPY5` | `708` |
+| `BTN_TRIGGER_HAPPY6` | `709` |
+| `BTN_TRIGGER_HAPPY7` | `710` |
+| `BTN_TRIGGER_HAPPY8` | `711` |
+| `BTN_TRIGGER_HAPPY9` | `712` |
+| `BTN_WEST` | `308` |
+| `BTN_WHEEL` | `336` |
+| `BTN_X` | `307` |
+| `BTN_Y` | `308` |
+| `BTN_Z` | `309` |
+
+## [`evdev.ecodes.ev`](https://github.com/BlueLua/evdev/blob/main/types/_enums.d.lua#L140-L156)
+
+| Name | Value |
+| -------------- | ----- |
+| `EV_ABS` | `3` |
+| `EV_CNT` | `32` |
+| `EV_FF` | `21` |
+| `EV_FF_STATUS` | `23` |
+| `EV_KEY` | `1` |
+| `EV_LED` | `17` |
+| `EV_MAX` | `31` |
+| `EV_MSC` | `4` |
+| `EV_PWR` | `22` |
+| `EV_REL` | `2` |
+| `EV_REP` | `20` |
+| `EV_SND` | `18` |
+| `EV_SW` | `5` |
+| `EV_SYN` | `0` |
+
+## [`evdev.ecodes.key`](https://github.com/BlueLua/evdev/blob/main/types/_enums.d.lua#L162-L688)
+
+| Name | Value |
+| ------------------------------ | ----- |
+| `KEY_0` | `11` |
+| `KEY_1` | `2` |
+| `KEY_102ND` | `86` |
+| `KEY_10CHANNELSDOWN` | `441` |
+| `KEY_10CHANNELSUP` | `440` |
+| `KEY_2` | `3` |
+| `KEY_3` | `4` |
+| `KEY_3D_MODE` | `623` |
+| `KEY_4` | `5` |
+| `KEY_5` | `6` |
+| `KEY_6` | `7` |
+| `KEY_7` | `8` |
+| `KEY_8` | `9` |
+| `KEY_9` | `10` |
+| `KEY_A` | `30` |
+| `KEY_AB` | `406` |
+| `KEY_ACCESSIBILITY` | `590` |
+| `KEY_ACTION_ON_SELECTION` | `596` |
+| `KEY_ADDRESSBOOK` | `429` |
+| `KEY_AGAIN` | `129` |
+| `KEY_ALL_APPLICATIONS` | `204` |
+| `KEY_ALS_TOGGLE` | `560` |
+| `KEY_ALTERASE` | `222` |
+| `KEY_ANGLE` | `371` |
+| `KEY_APOSTROPHE` | `40` |
+| `KEY_APPSELECT` | `580` |
+| `KEY_ARCHIVE` | `361` |
+| `KEY_ASPECT_RATIO` | `375` |
+| `KEY_ASSISTANT` | `583` |
+| `KEY_ATTENDANT_OFF` | `540` |
+| `KEY_ATTENDANT_ON` | `539` |
+| `KEY_ATTENDANT_TOGGLE` | `541` |
+| `KEY_AUDIO` | `392` |
+| `KEY_AUDIO_DESC` | `622` |
+| `KEY_AUTOPILOT_ENGAGE_TOGGLE` | `637` |
+| `KEY_AUX` | `390` |
+| `KEY_B` | `48` |
+| `KEY_BACK` | `158` |
+| `KEY_BACKSLASH` | `43` |
+| `KEY_BACKSPACE` | `14` |
+| `KEY_BASSBOOST` | `209` |
+| `KEY_BATTERY` | `236` |
+| `KEY_BLUE` | `401` |
+| `KEY_BLUETOOTH` | `237` |
+| `KEY_BOOKMARKS` | `156` |
+| `KEY_BREAK` | `411` |
+| `KEY_BRIGHTNESS_CYCLE` | `243` |
+| `KEY_BRIGHTNESS_MAX` | `593` |
+| `KEY_BRIGHTNESS_MENU` | `649` |
+| `KEY_BRIGHTNESS_MIN` | `592` |
+| `KEY_BRIGHTNESS_TOGGLE` | `431` |
+| `KEY_BRIGHTNESSDOWN` | `224` |
+| `KEY_BRIGHTNESSUP` | `225` |
+| `KEY_BRL_DOT1` | `497` |
+| `KEY_BRL_DOT10` | `506` |
+| `KEY_BRL_DOT2` | `498` |
+| `KEY_BRL_DOT3` | `499` |
+| `KEY_BRL_DOT4` | `500` |
+| `KEY_BRL_DOT5` | `501` |
+| `KEY_BRL_DOT6` | `502` |
+| `KEY_BRL_DOT7` | `503` |
+| `KEY_BRL_DOT8` | `504` |
+| `KEY_BRL_DOT9` | `505` |
+| `KEY_BUTTONCONFIG` | `576` |
+| `KEY_C` | `46` |
+| `KEY_CALC` | `140` |
+| `KEY_CALENDAR` | `397` |
+| `KEY_CAMERA` | `212` |
+| `KEY_CAMERA_ACCESS_DISABLE` | `588` |
+| `KEY_CAMERA_ACCESS_ENABLE` | `587` |
+| `KEY_CAMERA_ACCESS_TOGGLE` | `589` |
+| `KEY_CAMERA_DOWN` | `536` |
+| `KEY_CAMERA_FOCUS` | `528` |
+| `KEY_CAMERA_LEFT` | `537` |
+| `KEY_CAMERA_RIGHT` | `538` |
+| `KEY_CAMERA_UP` | `535` |
+| `KEY_CAMERA_ZOOMIN` | `533` |
+| `KEY_CAMERA_ZOOMOUT` | `534` |
+| `KEY_CANCEL` | `223` |
+| `KEY_CAPSLOCK` | `58` |
+| `KEY_CD` | `383` |
+| `KEY_CHANNEL` | `363` |
+| `KEY_CHANNELDOWN` | `403` |
+| `KEY_CHANNELUP` | `402` |
+| `KEY_CHAT` | `216` |
+| `KEY_CLEAR` | `355` |
+| `KEY_CLEARVU_SONAR` | `646` |
+| `KEY_CLOSE` | `206` |
+| `KEY_CLOSECD` | `160` |
+| `KEY_CNT` | `768` |
+| `KEY_COFFEE` | `152` |
+| `KEY_COMMA` | `51` |
+| `KEY_COMPOSE` | `127` |
+| `KEY_COMPUTER` | `157` |
+| `KEY_CONFIG` | `171` |
+| `KEY_CONNECT` | `218` |
+| `KEY_CONTEXT_MENU` | `438` |
+| `KEY_CONTEXTUAL_INSERT` | `597` |
+| `KEY_CONTEXTUAL_QUERY` | `598` |
+| `KEY_CONTROLPANEL` | `579` |
+| `KEY_COPY` | `133` |
+| `KEY_CUT` | `137` |
+| `KEY_CYCLEWINDOWS` | `154` |
+| `KEY_D` | `32` |
+| `KEY_DASHBOARD` | `204` |
+| `KEY_DATA` | `631` |
+| `KEY_DATABASE` | `426` |
+| `KEY_DEL_EOL` | `448` |
+| `KEY_DEL_EOS` | `449` |
+| `KEY_DEL_LINE` | `451` |
+| `KEY_DELETE` | `111` |
+| `KEY_DELETEFILE` | `146` |
+| `KEY_DICTATE` | `586` |
+| `KEY_DIGITS` | `413` |
+| `KEY_DIRECTION` | `153` |
+| `KEY_DIRECTORY` | `394` |
+| `KEY_DISPLAY_OFF` | `245` |
+| `KEY_DISPLAYTOGGLE` | `431` |
+| `KEY_DO_NOT_DISTURB` | `591` |
+| `KEY_DOCUMENTS` | `235` |
+| `KEY_DOLLAR` | `434` |
+| `KEY_DOT` | `52` |
+| `KEY_DOWN` | `108` |
+| `KEY_DUAL_RANGE_RADAR` | `643` |
+| `KEY_DVD` | `389` |
+| `KEY_E` | `18` |
+| `KEY_EDIT` | `176` |
+| `KEY_EDITOR` | `422` |
+| `KEY_EJECTCD` | `161` |
+| `KEY_EJECTCLOSECD` | `162` |
+| `KEY_EMAIL` | `215` |
+| `KEY_EMOJI_PICKER` | `585` |
+| `KEY_END` | `107` |
+| `KEY_ENTER` | `28` |
+| `KEY_EPG` | `365` |
+| `KEY_EPRIVACY_SCREEN_OFF` | `595` |
+| `KEY_EPRIVACY_SCREEN_ON` | `594` |
+| `KEY_EQUAL` | `13` |
+| `KEY_ESC` | `1` |
+| `KEY_EURO` | `435` |
+| `KEY_EXIT` | `174` |
+| `KEY_F` | `33` |
+| `KEY_F1` | `59` |
+| `KEY_F10` | `68` |
+| `KEY_F11` | `87` |
+| `KEY_F12` | `88` |
+| `KEY_F13` | `183` |
+| `KEY_F14` | `184` |
+| `KEY_F15` | `185` |
+| `KEY_F16` | `186` |
+| `KEY_F17` | `187` |
+| `KEY_F18` | `188` |
+| `KEY_F19` | `189` |
+| `KEY_F2` | `60` |
+| `KEY_F20` | `190` |
+| `KEY_F21` | `191` |
+| `KEY_F22` | `192` |
+| `KEY_F23` | `193` |
+| `KEY_F24` | `194` |
+| `KEY_F3` | `61` |
+| `KEY_F4` | `62` |
+| `KEY_F5` | `63` |
+| `KEY_F6` | `64` |
+| `KEY_F7` | `65` |
+| `KEY_F8` | `66` |
+| `KEY_F9` | `67` |
+| `KEY_FASTFORWARD` | `208` |
+| `KEY_FASTREVERSE` | `629` |
+| `KEY_FAVORITES` | `364` |
+| `KEY_FILE` | `144` |
+| `KEY_FINANCE` | `219` |
+| `KEY_FIND` | `136` |
+| `KEY_FIRST` | `404` |
+| `KEY_FISHING_CHART` | `641` |
+| `KEY_FN` | `464` |
+| `KEY_FN_1` | `478` |
+| `KEY_FN_2` | `479` |
+| `KEY_FN_B` | `484` |
+| `KEY_FN_D` | `480` |
+| `KEY_FN_E` | `481` |
+| `KEY_FN_ESC` | `465` |
+| `KEY_FN_F` | `482` |
+| `KEY_FN_F1` | `466` |
+| `KEY_FN_F10` | `475` |
+| `KEY_FN_F11` | `476` |
+| `KEY_FN_F12` | `477` |
+| `KEY_FN_F2` | `467` |
+| `KEY_FN_F3` | `468` |
+| `KEY_FN_F4` | `469` |
+| `KEY_FN_F5` | `470` |
+| `KEY_FN_F6` | `471` |
+| `KEY_FN_F7` | `472` |
+| `KEY_FN_F8` | `473` |
+| `KEY_FN_F9` | `474` |
+| `KEY_FN_RIGHT_SHIFT` | `485` |
+| `KEY_FN_S` | `483` |
+| `KEY_FORWARD` | `159` |
+| `KEY_FORWARDMAIL` | `233` |
+| `KEY_FRAMEBACK` | `436` |
+| `KEY_FRAMEFORWARD` | `437` |
+| `KEY_FRONT` | `132` |
+| `KEY_FULL_SCREEN` | `372` |
+| `KEY_G` | `34` |
+| `KEY_GAMES` | `417` |
+| `KEY_GOTO` | `354` |
+| `KEY_GRAPHICSEDITOR` | `424` |
+| `KEY_GRAVE` | `41` |
+| `KEY_GREEN` | `399` |
+| `KEY_H` | `35` |
+| `KEY_HANGEUL` | `122` |
+| `KEY_HANGUEL` | `122` |
+| `KEY_HANGUP_PHONE` | `446` |
+| `KEY_HANJA` | `123` |
+| `KEY_HELP` | `138` |
+| `KEY_HENKAN` | `92` |
+| `KEY_HIRAGANA` | `91` |
+| `KEY_HOME` | `102` |
+| `KEY_HOMEPAGE` | `172` |
+| `KEY_HP` | `211` |
+| `KEY_I` | `23` |
+| `KEY_IMAGES` | `442` |
+| `KEY_INFO` | `358` |
+| `KEY_INS_LINE` | `450` |
+| `KEY_INSERT` | `110` |
+| `KEY_ISO` | `170` |
+| `KEY_J` | `36` |
+| `KEY_JOURNAL` | `578` |
+| `KEY_K` | `37` |
+| `KEY_KATAKANA` | `90` |
+| `KEY_KATAKANAHIRAGANA` | `93` |
+| `KEY_KBD_LAYOUT_NEXT` | `584` |
+| `KEY_KBD_LCD_MENU1` | `696` |
+| `KEY_KBD_LCD_MENU2` | `697` |
+| `KEY_KBD_LCD_MENU3` | `698` |
+| `KEY_KBD_LCD_MENU4` | `699` |
+| `KEY_KBD_LCD_MENU5` | `700` |
+| `KEY_KBDILLUMDOWN` | `229` |
+| `KEY_KBDILLUMTOGGLE` | `228` |
+| `KEY_KBDILLUMUP` | `230` |
+| `KEY_KBDINPUTASSIST_ACCEPT` | `612` |
+| `KEY_KBDINPUTASSIST_CANCEL` | `613` |
+| `KEY_KBDINPUTASSIST_NEXT` | `609` |
+| `KEY_KBDINPUTASSIST_NEXTGROUP` | `611` |
+| `KEY_KBDINPUTASSIST_PREV` | `608` |
+| `KEY_KBDINPUTASSIST_PREVGROUP` | `610` |
+| `KEY_KEYBOARD` | `374` |
+| `KEY_KP0` | `82` |
+| `KEY_KP1` | `79` |
+| `KEY_KP2` | `80` |
+| `KEY_KP3` | `81` |
+| `KEY_KP4` | `75` |
+| `KEY_KP5` | `76` |
+| `KEY_KP6` | `77` |
+| `KEY_KP7` | `71` |
+| `KEY_KP8` | `72` |
+| `KEY_KP9` | `73` |
+| `KEY_KPASTERISK` | `55` |
+| `KEY_KPCOMMA` | `121` |
+| `KEY_KPDOT` | `83` |
+| `KEY_KPENTER` | `96` |
+| `KEY_KPEQUAL` | `117` |
+| `KEY_KPJPCOMMA` | `95` |
+| `KEY_KPLEFTPAREN` | `179` |
+| `KEY_KPMINUS` | `74` |
+| `KEY_KPPLUS` | `78` |
+| `KEY_KPPLUSMINUS` | `118` |
+| `KEY_KPRIGHTPAREN` | `180` |
+| `KEY_KPSLASH` | `98` |
+| `KEY_L` | `38` |
+| `KEY_LANGUAGE` | `368` |
+| `KEY_LAST` | `405` |
+| `KEY_LEFT` | `105` |
+| `KEY_LEFT_DOWN` | `617` |
+| `KEY_LEFT_UP` | `616` |
+| `KEY_LEFTALT` | `56` |
+| `KEY_LEFTBRACE` | `26` |
+| `KEY_LEFTCTRL` | `29` |
+| `KEY_LEFTMETA` | `125` |
+| `KEY_LEFTSHIFT` | `42` |
+| `KEY_LIGHTS_TOGGLE` | `542` |
+| `KEY_LINEFEED` | `101` |
+| `KEY_LINK_PHONE` | `447` |
+| `KEY_LIST` | `395` |
+| `KEY_LOGOFF` | `433` |
+| `KEY_M` | `50` |
+| `KEY_MACRO` | `112` |
+| `KEY_MACRO1` | `656` |
+| `KEY_MACRO10` | `665` |
+| `KEY_MACRO11` | `666` |
+| `KEY_MACRO12` | `667` |
+| `KEY_MACRO13` | `668` |
+| `KEY_MACRO14` | `669` |
+| `KEY_MACRO15` | `670` |
+| `KEY_MACRO16` | `671` |
+| `KEY_MACRO17` | `672` |
+| `KEY_MACRO18` | `673` |
+| `KEY_MACRO19` | `674` |
+| `KEY_MACRO2` | `657` |
+| `KEY_MACRO20` | `675` |
+| `KEY_MACRO21` | `676` |
+| `KEY_MACRO22` | `677` |
+| `KEY_MACRO23` | `678` |
+| `KEY_MACRO24` | `679` |
+| `KEY_MACRO25` | `680` |
+| `KEY_MACRO26` | `681` |
+| `KEY_MACRO27` | `682` |
+| `KEY_MACRO28` | `683` |
+| `KEY_MACRO29` | `684` |
+| `KEY_MACRO3` | `658` |
+| `KEY_MACRO30` | `685` |
+| `KEY_MACRO4` | `659` |
+| `KEY_MACRO5` | `660` |
+| `KEY_MACRO6` | `661` |
+| `KEY_MACRO7` | `662` |
+| `KEY_MACRO8` | `663` |
+| `KEY_MACRO9` | `664` |
+| `KEY_MACRO_PRESET1` | `691` |
+| `KEY_MACRO_PRESET2` | `692` |
+| `KEY_MACRO_PRESET3` | `693` |
+| `KEY_MACRO_PRESET_CYCLE` | `690` |
+| `KEY_MACRO_RECORD_START` | `688` |
+| `KEY_MACRO_RECORD_STOP` | `689` |
+| `KEY_MAIL` | `155` |
+| `KEY_MARK_WAYPOINT` | `638` |
+| `KEY_MAX` | `767` |
+| `KEY_MEDIA` | `226` |
+| `KEY_MEDIA_REPEAT` | `439` |
+| `KEY_MEDIA_TOP_MENU` | `619` |
+| `KEY_MEMO` | `396` |
+| `KEY_MENU` | `139` |
+| `KEY_MESSENGER` | `430` |
+| `KEY_MHP` | `367` |
+| `KEY_MICMUTE` | `248` |
+| `KEY_MIN_INTERESTING` | `113` |
+| `KEY_MINUS` | `12` |
+| `KEY_MODE` | `373` |
+| `KEY_MOVE` | `175` |
+| `KEY_MP3` | `391` |
+| `KEY_MSDOS` | `151` |
+| `KEY_MUHENKAN` | `94` |
+| `KEY_MUTE` | `113` |
+| `KEY_N` | `49` |
+| `KEY_NAV_CHART` | `640` |
+| `KEY_NAV_INFO` | `648` |
+| `KEY_NEW` | `181` |
+| `KEY_NEWS` | `427` |
+| `KEY_NEXT` | `407` |
+| `KEY_NEXT_ELEMENT` | `635` |
+| `KEY_NEXT_FAVORITE` | `624` |
+| `KEY_NEXTSONG` | `163` |
+| `KEY_NOTIFICATION_CENTER` | `444` |
+| `KEY_NUMERIC_0` | `512` |
+| `KEY_NUMERIC_1` | `513` |
+| `KEY_NUMERIC_11` | `620` |
+| `KEY_NUMERIC_12` | `621` |
+| `KEY_NUMERIC_2` | `514` |
+| `KEY_NUMERIC_3` | `515` |
+| `KEY_NUMERIC_4` | `516` |
+| `KEY_NUMERIC_5` | `517` |
+| `KEY_NUMERIC_6` | `518` |
+| `KEY_NUMERIC_7` | `519` |
+| `KEY_NUMERIC_8` | `520` |
+| `KEY_NUMERIC_9` | `521` |
+| `KEY_NUMERIC_A` | `524` |
+| `KEY_NUMERIC_B` | `525` |
+| `KEY_NUMERIC_C` | `526` |
+| `KEY_NUMERIC_D` | `527` |
+| `KEY_NUMERIC_POUND` | `523` |
+| `KEY_NUMERIC_STAR` | `522` |
+| `KEY_NUMLOCK` | `69` |
+| `KEY_O` | `24` |
+| `KEY_OK` | `352` |
+| `KEY_ONSCREEN_KEYBOARD` | `632` |
+| `KEY_OPEN` | `134` |
+| `KEY_OPTION` | `357` |
+| `KEY_P` | `25` |
+| `KEY_PAGEDOWN` | `109` |
+| `KEY_PAGEUP` | `104` |
+| `KEY_PASTE` | `135` |
+| `KEY_PAUSE` | `119` |
+| `KEY_PAUSE_RECORD` | `626` |
+| `KEY_PAUSECD` | `201` |
+| `KEY_PC` | `376` |
+| `KEY_PERFORMANCE` | `701` |
+| `KEY_PHONE` | `169` |
+| `KEY_PICKUP_PHONE` | `445` |
+| `KEY_PLAY` | `207` |
+| `KEY_PLAYCD` | `200` |
+| `KEY_PLAYER` | `387` |
+| `KEY_PLAYPAUSE` | `164` |
+| `KEY_POWER` | `116` |
+| `KEY_POWER2` | `356` |
+| `KEY_PRESENTATION` | `425` |
+| `KEY_PREVIOUS` | `412` |
+| `KEY_PREVIOUS_ELEMENT` | `636` |
+| `KEY_PREVIOUSSONG` | `165` |
+| `KEY_PRINT` | `210` |
+| `KEY_PRIVACY_SCREEN_TOGGLE` | `633` |
+| `KEY_PROG1` | `148` |
+| `KEY_PROG2` | `149` |
+| `KEY_PROG3` | `202` |
+| `KEY_PROG4` | `203` |
+| `KEY_PROGRAM` | `362` |
+| `KEY_PROPS` | `130` |
+| `KEY_PVR` | `366` |
+| `KEY_Q` | `16` |
+| `KEY_QUESTION` | `214` |
+| `KEY_R` | `19` |
+| `KEY_RADAR_OVERLAY` | `644` |
+| `KEY_RADIO` | `385` |
+| `KEY_RECORD` | `167` |
+| `KEY_RED` | `398` |
+| `KEY_REDO` | `182` |
+| `KEY_REFRESH` | `173` |
+| `KEY_REFRESH_RATE_TOGGLE` | `562` |
+| `KEY_REPLY` | `232` |
+| `KEY_RESERVED` | `0` |
+| `KEY_RESTART` | `408` |
+| `KEY_REWIND` | `168` |
+| `KEY_RFKILL` | `247` |
+| `KEY_RIGHT` | `106` |
+| `KEY_RIGHT_DOWN` | `615` |
+| `KEY_RIGHT_UP` | `614` |
+| `KEY_RIGHTALT` | `100` |
+| `KEY_RIGHTBRACE` | `27` |
+| `KEY_RIGHTCTRL` | `97` |
+| `KEY_RIGHTMETA` | `126` |
+| `KEY_RIGHTSHIFT` | `54` |
+| `KEY_RO` | `89` |
+| `KEY_ROOT_MENU` | `618` |
+| `KEY_ROTATE_DISPLAY` | `153` |
+| `KEY_ROTATE_LOCK_TOGGLE` | `561` |
+| `KEY_S` | `31` |
+| `KEY_SAT` | `381` |
+| `KEY_SAT2` | `382` |
+| `KEY_SAVE` | `234` |
+| `KEY_SCALE` | `120` |
+| `KEY_SCREEN` | `375` |
+| `KEY_SCREENLOCK` | `152` |
+| `KEY_SCREENSAVER` | `581` |
+| `KEY_SCROLLDOWN` | `178` |
+| `KEY_SCROLLLOCK` | `70` |
+| `KEY_SCROLLUP` | `177` |
+| `KEY_SEARCH` | `217` |
+| `KEY_SELECT` | `353` |
+| `KEY_SELECTIVE_SCREENSHOT` | `634` |
+| `KEY_SEMICOLON` | `39` |
+| `KEY_SEND` | `231` |
+| `KEY_SENDFILE` | `145` |
+| `KEY_SETUP` | `141` |
+| `KEY_SHOP` | `221` |
+| `KEY_SHUFFLE` | `410` |
+| `KEY_SIDEVU_SONAR` | `647` |
+| `KEY_SINGLE_RANGE_RADAR` | `642` |
+| `KEY_SLASH` | `53` |
+| `KEY_SLEEP` | `142` |
+| `KEY_SLOW` | `409` |
+| `KEY_SLOWREVERSE` | `630` |
+| `KEY_SOS` | `639` |
+| `KEY_SOUND` | `213` |
+| `KEY_SPACE` | `57` |
+| `KEY_SPELLCHECK` | `432` |
+| `KEY_SPORT` | `220` |
+| `KEY_SPREADSHEET` | `423` |
+| `KEY_STOP` | `128` |
+| `KEY_STOP_RECORD` | `625` |
+| `KEY_STOPCD` | `166` |
+| `KEY_SUBTITLE` | `370` |
+| `KEY_SUSPEND` | `205` |
+| `KEY_SYSRQ` | `99` |
+| `KEY_T` | `20` |
+| `KEY_TAB` | `15` |
+| `KEY_TAPE` | `384` |
+| `KEY_TASKMANAGER` | `577` |
+| `KEY_TEEN` | `414` |
+| `KEY_TEXT` | `388` |
+| `KEY_TIME` | `359` |
+| `KEY_TITLE` | `369` |
+| `KEY_TOUCHPAD_OFF` | `532` |
+| `KEY_TOUCHPAD_ON` | `531` |
+| `KEY_TOUCHPAD_TOGGLE` | `530` |
+| `KEY_TRADITIONAL_SONAR` | `645` |
+| `KEY_TUNER` | `386` |
+| `KEY_TV` | `377` |
+| `KEY_TV2` | `378` |
+| `KEY_TWEN` | `415` |
+| `KEY_U` | `22` |
+| `KEY_UNDO` | `131` |
+| `KEY_UNKNOWN` | `240` |
+| `KEY_UNMUTE` | `628` |
+| `KEY_UP` | `103` |
+| `KEY_UWB` | `239` |
+| `KEY_V` | `47` |
+| `KEY_VCR` | `379` |
+| `KEY_VCR2` | `380` |
+| `KEY_VENDOR` | `360` |
+| `KEY_VIDEO` | `393` |
+| `KEY_VIDEO_NEXT` | `241` |
+| `KEY_VIDEO_PREV` | `242` |
+| `KEY_VIDEOPHONE` | `416` |
+| `KEY_VOD` | `627` |
+| `KEY_VOICECOMMAND` | `582` |
+| `KEY_VOICEMAIL` | `428` |
+| `KEY_VOLUMEDOWN` | `114` |
+| `KEY_VOLUMEUP` | `115` |
+| `KEY_W` | `17` |
+| `KEY_WAKEUP` | `143` |
+| `KEY_WIMAX` | `246` |
+| `KEY_WLAN` | `238` |
+| `KEY_WORDPROCESSOR` | `421` |
+| `KEY_WPS_BUTTON` | `529` |
+| `KEY_WWAN` | `246` |
+| `KEY_WWW` | `150` |
+| `KEY_X` | `45` |
+| `KEY_XFER` | `147` |
+| `KEY_Y` | `21` |
+| `KEY_YELLOW` | `400` |
+| `KEY_YEN` | `124` |
+| `KEY_Z` | `44` |
+| `KEY_ZENKAKUHANKAKU` | `85` |
+| `KEY_ZOOM` | `372` |
+| `KEY_ZOOMIN` | `418` |
+| `KEY_ZOOMOUT` | `419` |
+| `KEY_ZOOMRESET` | `420` |
+
+## [`evdev.ecodes.rel`](https://github.com/BlueLua/evdev/blob/main/types/_enums.d.lua#L694-L711)
+
+| Name | Value |
+| ------------------- | ----- |
+| `REL_CNT` | `16` |
+| `REL_DIAL` | `7` |
+| `REL_HWHEEL` | `6` |
+| `REL_HWHEEL_HI_RES` | `12` |
+| `REL_MAX` | `15` |
+| `REL_MISC` | `9` |
+| `REL_RESERVED` | `10` |
+| `REL_RX` | `3` |
+| `REL_RY` | `4` |
+| `REL_RZ` | `5` |
+| `REL_WHEEL` | `8` |
+| `REL_WHEEL_HI_RES` | `11` |
+| `REL_X` | `0` |
+| `REL_Y` | `1` |
+| `REL_Z` | `2` |
+
+## [`evdev.ecodes.syn`](https://github.com/BlueLua/evdev/blob/main/types/_enums.d.lua#L717-L725)
+
+| Name | Value |
+| --------------- | ----- |
+| `SYN_CNT` | `16` |
+| `SYN_CONFIG` | `1` |
+| `SYN_DROPPED` | `3` |
+| `SYN_MAX` | `15` |
+| `SYN_MT_REPORT` | `2` |
+| `SYN_REPORT` | `0` |
+
+## [`evdev.event`](https://github.com/BlueLua/evdev/blob/main/types/device.d.lua#L3-L13)
+
+A Linux input event.
+
+| Field | Type | Optional | Description |
+| -------- | -------------------- | -------- | ----------------------------------------------------------- |
+| `code` | `integer` | No | Key/button/axis code, e.g. `KEY_A`. |
+| `device` | [`evdev.Device`] | Yes | The Device object that produced this event. |
+| `sec` | `integer` | Yes | Timestamp seconds. |
+| `type` | [`evdev.ecodes.ev`] | No | Event type, e.g. `EV_KEY`. |
+| `usec` | `integer` | Yes | Timestamp microseconds. |
+| `value` | [`evdev.eventValue`] | No | Event value, e.g. `0` = release, `1` = press, `2` = repeat. |
+
+## [`evdev.eventValue`](https://github.com/BlueLua/evdev/blob/main/types/evdev.d.lua#L3-L6)
+
+Numeric value attached to an input event.
+
+`integer`
+
+## [`evdev.fd`](https://github.com/BlueLua/evdev/blob/main/types/evdev.d.lua#L3-L6)
+
+Linux file descriptor number.
+
+`integer`
+
+## [`evdev.path`](https://github.com/BlueLua/evdev/blob/main/types/evdev.d.lua#L3-L6)
+
+Path to an evdev device node or related input path.
+
+`string`
+
+## [`evdev.uinputSpec`](https://github.com/BlueLua/evdev/blob/main/types/uinput.d.lua#L3-L16)
+
+Configuration used to create a `/dev/uinput` virtual device.
+
+| Field | Type | Optional | Description |
+| ------------- | ---------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
+| `bustype` | `integer` | Yes | Linux bus type (default: `BUS_USB` / 3). |
+| `event_types` | [`evdev.ecodes.ev`]`[]` | Yes | Event types to enable. Defaults to `EV_SYN`, plus `EV_KEY`/`EV_REP` for keyboard keys and `EV_REL` for relative axes. |
+| `keys` | `(`[`evdev.ecodes.key`] \| [`evdev.ecodes.btn`]`)[]` | Yes | Keys/buttons to expose. Defaults to all real `KEY_*` and `BTN_*` codes when omitted. |
+| `name` | `string` | Yes | Device name shown by the kernel (default: `"Lua evdev virtual keyboard"`). |
+| `path` | `string` | Yes | uinput control node (default: `"/dev/uinput"`). Kernel assigns `/dev/input/eventX`. |
+| `product` | `integer` | Yes | Product ID (default: `0xE7DE`). |
+| `rels` | [`evdev.ecodes.rel`]`[]` | Yes | Relative axes to expose. Defaults to all real `REL_*` codes when omitted. |
+| `vendor` | `integer` | Yes | Vendor ID (default: `0x1209`). |
+| `version` | `integer` | Yes | Version number (default: `1`). |
+
+
+
+[`evdev.Device`]: /evdev/api/device
+[`evdev.deviceInfo`]: /evdev/types#evdev-deviceinfo
+[`evdev.ecodes.btn`]: /evdev/api/ecodes
+[`evdev.ecodes.ev`]: /evdev/api/ecodes
+[`evdev.ecodes.key`]: /evdev/api/ecodes
+[`evdev.ecodes.rel`]: /evdev/api/ecodes
+[`evdev.eventValue`]: /evdev/types#evdev-eventvalue
+[`evdev.event`]: /evdev/types#evdev-event
+[`evdev.fd`]: /evdev/types#evdev-fd
+
+