diff --git a/docs/docs/config/pointers.md b/docs/docs/config/pointers.md new file mode 100644 index 00000000000..64c03b85159 --- /dev/null +++ b/docs/docs/config/pointers.md @@ -0,0 +1,67 @@ +--- +title: Pointer Configuration +sidebar_label: Pointers +--- + +These are settings related to the pointer/mouse support in ZMK. + +See [Configuration Overview](index.md) for instructions on how to change these settings. + +## Kconfig + +Definition file: [zmk/app/mouse/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/app/mouse/Kconfig) + +### General + +| Config | Type | Description | Default | +| ----------------------------------- | ---- | -------------------------------------------------------------------------- | ------- | +| `CONFIG_ZMK_MOUSE` | bool | Enable the general pointer/mouse functionality | n | +| `CONFIG_ZMK_MOUSE_SMOOTH_SCROLLING` | bool | Enable smooth scrolling HID functionality (via HID Resolution Multipliers) | n | + +### Zephyr Settings + +The following settings are from Zephyr, and should be defaulted to sane values, but can be adjusted if you encounter problems + +| Config | Type | Description | Default | +| -------------------------------- | ---- | ---------------------------------------------------------- | ------------------------------- | +| `CONFIG_INPUT_THREAD_STACK_SIZE` | int | Stack size for the dedicated input event processing thread | 512 (1024 on split peripherals) | + +## Input Listener + +TODO: Complete description + +### Devicetree + +Applies to: `compatible = "zmk,input-listener"` + +Definition file: [zmk/app/dts/bindings/zmk,input-listener.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/zmk%2Cinput-listener.yaml) + +| Property | Type | Description | Default | +| ------------------ | ------ | ------------------------------------------------------------------- | ------- | +| `device` | handle | Input device handle | | +| `input-processors` | array | List of input processors (with parameters) to apply to input events | | + +#### Child Properties + +Additional properties can be set on child nodes, which allows changing the settings when certain layers are enabled: + +| Property | Type | Description | Default | +| ------------------ | ----- | ------------------------------------------------------------------------------------------------ | ------- | +| `layers` | array | List of layer indexes. This config will apply if any layer in the list is active. | | +| `input-processors` | array | List of input processors (with parameters) to apply to input events | | +| `inherit` | flag | Whether to first apply the base input processors before the processors specific to this override | | + +## Input Split + +TODO: Complete description + +### Devicetree + +Applies to: `compatible = "zmk,input-split"` + +Definition file: [zmk/app/dts/bindings/zmk,input-split.yaml](https://github.com/zmkfirmware/zmk/blob/main/app/dts/bindings/zmk%2Cinput-split.yaml) + +| Property | Type | Description | Default | +| ------------------ | ------ | ------------------------------------------------------------------- | ------- | +| `device` | handle | Input device handle | | +| `input-processors` | array | List of input processors (with parameters) to apply to input events | | diff --git a/docs/docs/development/hardware-integration/pointers.md b/docs/docs/development/hardware-integration/pointers.md new file mode 100644 index 00000000000..1e9e2795a2f --- /dev/null +++ b/docs/docs/development/hardware-integration/pointers.md @@ -0,0 +1,82 @@ +--- +title: Pointing Devices +sidebar_label: Pointers +--- + +ZMK's pointer support builds upon the Zephyr [input API](https://docs.zephyrproject.org/3.5.0/services/input/index.html) to offer pointer/mouse functionality with various hardware. A limited number of input drivers are available in the Zephyr 3.5 version currently used by ZMK, but additional drivers can be found in [external modules](../../features/modules.mdx) for a variety of hardware. + +## Listeners + +## Split + +## Input Processors + +## Configuration File + +In your configuration file you will need to add the following lines so that the encoders can be enabled/disabled: + +```ini +# Uncomment to enable encoder +# CONFIG_EC11=y +# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y +``` + +These should be commented by default for encoders that are optional/can be swapped with switches, but can be uncommented if encoders are part of the default design. + +:::note +If building locally for split boards, you may need to add these lines to the specific half's configuration file as well as the combined configuration file, see the [configuration overview](../../config/index.md) for details. +::: + +## Devicetree File + +In your devicetree file you will need to define each sensor with their properties. For split keyboards, do this in the .dtsi file that is shared by all parts; otherwise do it in the .dts (for boards) or .overlay (shields) file, see [configuration overview](../../config/index.md#devicetree-files) for details. Add the following lines: + +```dts + left_encoder: encoder_left { + compatible = "alps,ec11"; + a-gpios = ; + b-gpios = ; + steps = <80>; + status = "disabled"; + }; +``` + +Here you need to replace `PIN_A` and `PIN_B` with the appropriate pins that your PCB utilizes for the encoder(s). See shield overlays section in the [new shield guide](new-shield.mdx#shield-overlays) on the appropriate node label and pin number to use for GPIOs. + +The `steps` property should corresponded to the documented pulses per rotation for the encoders used on the keyboard, typically found on the datasheet of the component. If users use different encoders when they build, the value can be overridden in their keymap. + +Add additional encoders as necessary by duplicating the above lines, replacing `left` with whatever you would like to call your encoder, and updating the pins. + +Once you have defined the encoder sensors, you will have to add them to the list of sensors: + +```dts + sensors: sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder &right_encoder>; + triggers-per-rotation = <20>; + }; +``` + +In this example, a `left_encoder` and `right_encoder` are both added. Additional encoders can be added with spaces separating each, and the order they are added here determines the order in which you define their behavior in your keymap. + +In addition, a default value for the number of times the sensors trigger the bound behavior per full rotation is set via the `triggers-per-rotation` property. See [Encoders Config](../../config/encoders.md#devicetree) for more details. + +Add the following lines to the .dts/.overlay file that contains the encoder to enable it: + +```dts +&left_encoder { + status = "okay"; +}; +``` + +Make sure to add this to the .dts/.overlay file, rather than any shared (.dtsi) files. + +## Keymap + +Add the following line to your keymap file to add default encoder behavior bindings: + +```dts +sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; +``` + +Add additional bindings as necessary to match the default number of encoders on your board. See the [Encoders](../../features/encoders.md) and [Keymaps](../../keymaps/index.mdx) documentation pages for more details. diff --git a/docs/docs/features/pointers.md b/docs/docs/features/pointers.md new file mode 100644 index 00000000000..0423a632d68 --- /dev/null +++ b/docs/docs/features/pointers.md @@ -0,0 +1,33 @@ +--- +title: Pointers +--- + +ZMK supports physical pointing devices, as well as [mouse emulation behaviors](../keymaps/behaviors/mouse-emulation.md) for sending HID pointing events to hosts. + +## Configuration + +To enable the pointer functionality, you must set `CONFIG_ZMK_MOUSE=y` in your config. See the [pointer configuration](../config/pointers.md) for the full details. + +:::warning + +When enabling the feature, changes are made to the HID report descriptor, which may not get picked up automatically over BLE to some hosts. Be sure to remove and re-pair to your hosts once you enable the feature + +::: + +## Mouse Emulation + +Mouse emulation allows you to use your keyboard as a pointing device without using dedicated pointer hardware, like an integrated trackpad, trackball, etc. By adding new bindings in your keymap like `&mmv MOVE_UP` you can make key presses send mouse HID events to your connected hosts. + +See the [mouse emulation behaviors](../keymaps/behaviors/mouse-emulation.md) for details. + +## Physical Pointers + +There are a few drivers available for supported physical pointing devices integrated into ZMK powered device. When doing so, you can use your device as both a keyboard and a pointing device with any connected hosts. The functionality can be extended further, e.g. slow mode, scroll mode, temporary mouse layers, etc. by configuring input processors linked to the physical pointing device. + +## Input Processors + +Input processors are small pieces of functionality that process and optionally modify events generated from emulated and physical pointing devices. Processors can do things like scaling movement values to make them larger or smaller for detailed work, swapping the event types to turn movements into scroll events, or temporarily enabling an extra layer while the pointer is in use. + +## Input Listeners + +Listeners are the key piece that integrate the low level input devices to the rest of the ZMK system. In particular, listeners subscribe to input events from the linked device, and when a given event occurs (e.g. X/Y movement), apply any input processors before sending those events to the HID system for notification to the host. The main way to modify the way a pointer behaves is by configuring the input processors for a given listener. diff --git a/docs/docs/keymaps/behaviors/mouse-emulation.md b/docs/docs/keymaps/behaviors/mouse-emulation.md index 553676ec4d2..91b8ca6b33a 100644 --- a/docs/docs/keymaps/behaviors/mouse-emulation.md +++ b/docs/docs/keymaps/behaviors/mouse-emulation.md @@ -67,6 +67,16 @@ This example will send press of the fourth mouse button when the binding is trig &mkp MB4 ``` +### Input Processors + +If you want to apply any [input processors](../input-processors/index.md#input-processors-overview) to `&mkp` you can do so by referencing `&mkp_input_listener`, e.g.: + +```dts +&mkp_input_listener { + input-processors = <&zip_temp_layer 2 2000>; +} +``` + ## Mouse Move This behavior sends mouse X/Y movement events to the connected host. @@ -99,6 +109,16 @@ The following will send a left mouse movement event to the host when pressed/hel &mmv MOVE_LEFT ``` +### Input Processors + +If you want to apply any [input processors](../input-processors/index.md#input-processors-overview) to `&mkp` you can do so by referencing `&mmv_input_listener`, e.g.: + +```dts +&mmv_input_listener { + input-processors = <&zip_temp_layer 2 2000>; +} +``` + ## Mouse Scroll This behavior sends vertical and horizontal scroll events to the connected host. @@ -130,3 +150,13 @@ The following will send a scroll left event to the host when pressed/held: ``` &msc MOVE_LEFT ``` + +### Input Processors + +If you want to apply any [input processors](../input-processors/index.md#input-processors-overview) to `&mkp` you can do so by referencing `&msc_input_listener`, e.g.: + +```dts +&msc_input_listener { + input-processors = <&zip_temp_layer 2 2000>; +} +``` diff --git a/docs/docs/keymaps/input-processors/code-mapper.md b/docs/docs/keymaps/input-processors/code-mapper.md new file mode 100644 index 00000000000..900f8d773ac --- /dev/null +++ b/docs/docs/keymaps/input-processors/code-mapper.md @@ -0,0 +1,4 @@ +--- +title: Code Mapper Input Processor +sidebar_label: Code Mapper +--- diff --git a/docs/docs/keymaps/input-processors/index.md b/docs/docs/keymaps/input-processors/index.md new file mode 100644 index 00000000000..df175ce88b4 --- /dev/null +++ b/docs/docs/keymaps/input-processors/index.md @@ -0,0 +1,35 @@ +--- +title: Input Processor Overview +sidebar_label: Overview +--- + +# Input Processors Overview + +"Input processors" are small pieces of functionality that process and optionally modify events generated from emulated and physical pointing devices. Processors can do things like scaling movement values to make them larger or smaller for detailed work, swapping the event types to turn movements into scroll events, or temporarily enabling an extra layer while the pointer is in use. + +Below is a summary of pre-defined input processors and user-definable input processors available in ZMK, with references to documentation pages describing them. + +## Pre-Defined + +A set of predefined input processors is available by adding the following at the top of your keymap/overlay file: + +``` +#include +``` + +Once included, you can use the following: + +| Binding | Behavior | Description | +| -------------------------- | -------------------------------------------- | ------------------------------------------------------------------- | +| `&zip_xy_scaler` | [XY Scaler](scaler.md#pre-defined-instances) | Scale a the X/Y input events using a multiplier and divisor | +| `&zip_x_scaler` | [X Scaler](scaler.md#pre-defined-instances) | Scale a the X input events using a multiplier and divisor | +| `&zip_y_scaler` | [Y Scaler](scaler.md#pre-defined-instances) | Scale a the Y input events using a multiplier and divisor | +| `&zip_xy_transform` | [XY Transform](transformer.md) | Transform X/Y values, e.g. inverting or swapping | +| `&zip_scroll_transform` | [Scroll Transform](transformer.md) | Transform wheel/horizontal wheel values, e.g. inverting or swapping | +| `&zip_xy_to_scroll_mapper` | [XY To Scroll Mapper](code-mapper.md) | Map X/Y values to scroll wheel/horizontal wheel events | +| `&zip_xy_swap_mapper` | [XY Swap Mapper](code-mapper.md) | Swap X/Y values | +| `&zip_temp_layer` | [Temporary Layer](temp-layer.md) | Temporarily enable a layer during pointer use | + +## Used-Defined + +Several of the input processors that have predefined instances, e.g. `&zip_xy_scaler` or `&zip_xy_to_scroll_mapper` can also have new instances created with custom properties around which input codes to scale, or which codes to map, etc. diff --git a/docs/docs/keymaps/input-processors/scaler.md b/docs/docs/keymaps/input-processors/scaler.md new file mode 100644 index 00000000000..5cd4e35bbca --- /dev/null +++ b/docs/docs/keymaps/input-processors/scaler.md @@ -0,0 +1,70 @@ +--- +title: Scaler Input Processor +sidebar_label: Scaler +--- + +## Overview + +The scaler input processor is used to scale the value of an input event that has a code matching the codes set on the scaler. Events with other codes will be ignored. Values are scaled by multiplying by the multiplier parameter, and then dividing by the divisor parameter. + +## Usage + +When used, a scaler takes two parameters, a multiplier and a divisor, e.g.: + +```dts +&zip_xy_scaler 2 1 +``` + +which will double all the X/Y movement, or: + +```dts +&zip_xy_scaler 1 3 +``` + +which will make movements more granular. + +## Pre-Defined Instances + +Three pre-defined instance of the scaler input processor are available: + +| Reference | Description | +| ---------------- | --------------------------------------------- | +| `&zip_xy_scaler` | Scale X- and Y-axis values by the same amount | +| `&zip_x_scaler` | Scale X-axis values | +| `&zip_y_scaler` | Scale X-axis values | + +## User Defined Instances + +Users can define new instances of the scaler input processor if they want to target different codes. + +### Example + +```dts +#include + +/ { + input_processors { + zip_wheel_scaler: zip_wheel_scaler { + compatible = "zmk,input-processor-scaler"; + #input-processor-cells = <2>; + type = ; + codes = ; + track-remainders; + }; + }; +} +``` + +### Compatible + +The scaler input processor uses a `compatible` property of `"zmk,input-processor-scaler"`. + +### Standard Properties + +- `#input-processor-cells` - required to be contant value of `<2>`. +- `track-remainders` - boolean flag that indicates callers should allow the processor to track remainders between events. + +### User Properties + +- `type` - The [type](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/include/zephyr/dt-bindings/input/input-event-codes.h#L25) of events to scale. Usually, this is `INPUT_EV_REL` for relative events. +- `codes` - The specific codes within the given type to scale, e.g. [relative event codes](https://github.com/zmkfirmware/zephyr/blob/v3.5.0%2Bzmk-fixes/include/zephyr/dt-bindings/input/input-event-codes.h#L245) diff --git a/docs/docs/keymaps/input-processors/temp-layer.md b/docs/docs/keymaps/input-processors/temp-layer.md new file mode 100644 index 00000000000..d16b7c4125d --- /dev/null +++ b/docs/docs/keymaps/input-processors/temp-layer.md @@ -0,0 +1,4 @@ +--- +title: Temporary Layer Input Processor +sidebar_label: Temporary Layer +--- diff --git a/docs/docs/keymaps/input-processors/transformer.md b/docs/docs/keymaps/input-processors/transformer.md new file mode 100644 index 00000000000..900f8d773ac --- /dev/null +++ b/docs/docs/keymaps/input-processors/transformer.md @@ -0,0 +1,4 @@ +--- +title: Code Mapper Input Processor +sidebar_label: Code Mapper +--- diff --git a/docs/sidebars.js b/docs/sidebars.js index 4c278d4bbec..e8b399f5871 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -38,6 +38,7 @@ module.exports = { "features/battery", "features/soft-off", "features/encoders", + "features/pointers", "features/displays", "features/backlight", "features/underglow", @@ -91,6 +92,21 @@ module.exports = { "keymaps/combos", "keymaps/conditional-layers", "keymaps/list-of-keycodes", + { + type: "category", + label: "Input Processors", + link: { + type: "doc", + id: "keymaps/input-processors/index", + }, + collapsed: true, + items: [ + "keymaps/input-processors/scaler", + "keymaps/input-processors/transformer", + "keymaps/input-processors/code-mapper", + "keymaps/input-processors/temp-layer", + ], + }, ], }, { @@ -109,6 +125,7 @@ module.exports = { "config/combos", "config/displays", "config/encoders", + "config/pointers", "config/keymap", "config/layout", "config/kscan", @@ -131,6 +148,7 @@ module.exports = { "development/hardware-integration/boards-shields-keymaps", "development/hardware-integration/shift-registers", "development/hardware-integration/encoders", + "development/hardware-integration/pointers", ], }, {