feat(mouse): Add mouse move and scroll support (#2477)
* feat(mouse): Add mouse move and scroll support
* Use Zephyr input subsystem for all pointers.
* Input processors for modifying events, e.g. scaling, swapping
codes, temporary (mouse) layers, etc.
* Mouse move/scroll behaviors.
* Infrastructure in place for physical pointer input devices.
* feat: Add input split support.
* docs: Add initial pointer docs.
---------
Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
Co-authored-by: Alexander Krikun <krikun98@gmail.com>
Co-authored-by: Robert U <urob@users.noreply.github.com>
Co-authored-by: Shawn Meier <ftc@users.noreply.github.com>
Co-authored-by: Chris Andreae <chris@andreae.gen.nz>
Co-authored-by: Anant Thazhemadam <47104651+thazhemadam@users.noreply.github.com>
Co-authored-by: Erik Tollerud <erik.tollerud@gmail.com>
Co-authored-by: Nicolas Munnich <98408764+Nick-Munnich@users.noreply.github.com>
This commit is contained in:
parent
7e8c542c94
commit
6b40bfda53
119 changed files with 4223 additions and 229 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/init.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
|
@ -175,6 +176,45 @@ static ssize_t split_svc_get_selected_phys_layout(struct bt_conn *conn,
|
|||
return bt_gatt_attr_read(conn, attrs, buf, len, offset, &selected, sizeof(selected));
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT)
|
||||
|
||||
static void split_input_events_ccc(const struct bt_gatt_attr *attr, uint16_t value) {
|
||||
LOG_DBG("value %d", value);
|
||||
}
|
||||
|
||||
// Duplicated from Zephyr, since it is internal there
|
||||
struct gatt_cpf {
|
||||
uint8_t format;
|
||||
int8_t exponent;
|
||||
uint16_t unit;
|
||||
uint8_t name_space;
|
||||
uint16_t description;
|
||||
} __packed;
|
||||
|
||||
ssize_t bt_gatt_attr_read_input_split_cpf(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
void *buf, uint16_t len, uint16_t offset) {
|
||||
uint16_t reg = (uint16_t)(uint32_t)attr->user_data;
|
||||
struct gatt_cpf value;
|
||||
|
||||
value.format = 0x1B; // Struct
|
||||
value.exponent = 0;
|
||||
value.unit = sys_cpu_to_le16(0x2700); // Unitless
|
||||
value.name_space = 0x01; // Bluetooth SIG
|
||||
value.description = sys_cpu_to_le16(reg);
|
||||
|
||||
return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, sizeof(value));
|
||||
}
|
||||
|
||||
#define INPUT_SPLIT_CHARS(node_id) \
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_INPUT_EVENT_UUID), \
|
||||
BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ_ENCRYPT, NULL, NULL, NULL), \
|
||||
BT_GATT_CCC(split_input_events_ccc, \
|
||||
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT), \
|
||||
BT_GATT_DESCRIPTOR(BT_UUID_GATT_CPF, BT_GATT_PERM_READ, bt_gatt_attr_read_input_split_cpf, \
|
||||
NULL, (void *)DT_REG_ADDR(node_id)),
|
||||
|
||||
#endif
|
||||
|
||||
BT_GATT_SERVICE_DEFINE(
|
||||
split_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID)),
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID),
|
||||
|
|
@ -192,10 +232,11 @@ BT_GATT_SERVICE_DEFINE(
|
|||
split_svc_sensor_state, NULL, &last_sensor_event),
|
||||
BT_GATT_CCC(split_svc_sensor_state_ccc, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||
DT_FOREACH_STATUS_OKAY(zmk_input_split, INPUT_SPLIT_CHARS)
|
||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID),
|
||||
BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL,
|
||||
split_svc_update_indicators, NULL),
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_UPDATE_HID_INDICATORS_UUID),
|
||||
BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE_ENCRYPT, NULL,
|
||||
split_svc_update_indicators, NULL),
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_PERIPHERAL_HID_INDICATORS)
|
||||
BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SELECT_PHYS_LAYOUT_UUID),
|
||||
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ,
|
||||
|
|
@ -306,6 +347,29 @@ int zmk_split_bt_sensor_triggered(uint8_t sensor_index,
|
|||
}
|
||||
#endif /* ZMK_KEYMAP_HAS_SENSORS */
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT)
|
||||
|
||||
int zmk_split_bt_report_input(uint8_t reg, uint8_t type, uint16_t code, int32_t value, bool sync) {
|
||||
|
||||
for (size_t i = 0; i < split_svc.attr_count; i++) {
|
||||
if (bt_uuid_cmp(split_svc.attrs[i].uuid,
|
||||
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_INPUT_EVENT_UUID)) == 0 &&
|
||||
(uint8_t)(uint32_t)split_svc.attrs[i + 2].user_data == reg) {
|
||||
struct zmk_split_input_event_payload payload = {
|
||||
.type = type,
|
||||
.code = code,
|
||||
.value = value,
|
||||
.sync = sync ? 1 : 0,
|
||||
};
|
||||
|
||||
return bt_gatt_notify(NULL, &split_svc.attrs[i], &payload, sizeof(payload));
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_ZMK_INPUT_SPLIT) */
|
||||
|
||||
static int service_init(void) {
|
||||
static const struct k_work_queue_config queue_config = {
|
||||
.name = "Split Peripheral Notification Queue"};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue