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 + +