Skip to content

Commit

Permalink
input: make short-inputs optional
Browse files Browse the repository at this point in the history
By making short inputs optional, the user can bypass short-events all
together if necessary (e.g. custom button-press listener).

Signed-off-by: Juliane Schulze <[email protected]>
  • Loading branch information
deveritec-rosc authored and fabiobaltieri committed Nov 23, 2023
1 parent c3a54ae commit eeb6bf7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
9 changes: 6 additions & 3 deletions dts/bindings/input/zephyr,input-longpress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ description: |
corresponding to short and long press.
Can be optionally be associated to a specific device to listen for events
only from that device. Example configuration:
only from that device.
Example configuration:
#include <zephyr/dt-bindings/input/input-event-codes.h>
Expand All @@ -23,12 +25,14 @@ description: |
Example output:
# short press
input event: dev=buttons SYN type= 1 code= 11 value=1 # INPUT_KEY_0 press
# release before one second
input event: dev=buttons SYN type= 1 code= 11 value=0 # INPUT_KEY_0 release
input event: dev=longpress SYN type= 1 code= 30 value=1 # INPUT_KEY_A press
input event: dev=longpress SYN type= 1 code= 30 value=0 # INPUT_KEY_A release
# long press
input event: dev=buttons SYN type= 1 code= 11 value=1 # INPUT_KEY_0 press
# hold for more than one second
input event: dev=longpress SYN type= 1 code= 45 value=1 # INPUT_KEY_X press
Expand All @@ -52,9 +56,8 @@ properties:
short-codes:
type: array
required: true
description: |
Array of key codes to be generated for short press (INPUT_KEY_* or
Optional array of key codes to be generated for short press (INPUT_KEY_* or
INPUT_BTN_*).
long-codes:
Expand Down
11 changes: 8 additions & 3 deletions subsys/input/input_longpress.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static void longpress_cb(const struct device *dev, struct input_event *evt)
k_work_cancel_delayable(&entry->work);
if (entry->long_fired) {
input_report_key(dev, cfg->long_codes[i], 0, true, K_FOREVER);
} else {
} else if (cfg->short_codes != NULL) {
input_report_key(dev, cfg->short_codes[i], 1, true, K_FOREVER);
input_report_key(dev, cfg->short_codes[i], 0, true, K_FOREVER);
}
Expand Down Expand Up @@ -109,8 +109,9 @@ static int longpress_init(const struct device *dev)
}

#define INPUT_LONGPRESS_DEFINE(inst) \
BUILD_ASSERT(DT_INST_PROP_LEN(inst, input_codes) == \
DT_INST_PROP_LEN(inst, short_codes)); \
BUILD_ASSERT((DT_INST_PROP_LEN(inst, input_codes) == \
DT_INST_PROP_LEN_OR(inst, short_codes, 0)) || \
!DT_INST_NODE_HAS_PROP(inst, short_codes)); \
BUILD_ASSERT(DT_INST_PROP_LEN(inst, input_codes) == \
DT_INST_PROP_LEN(inst, long_codes)); \
static void longpress_cb_##inst(struct input_event *evt) \
Expand All @@ -120,12 +121,16 @@ static int longpress_init(const struct device *dev)
INPUT_CALLBACK_DEFINE(DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, input)), \
longpress_cb_##inst); \
static const uint16_t longpress_input_codes_##inst[] = DT_INST_PROP(inst, input_codes); \
IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, short_codes), ( \
static const uint16_t longpress_short_codes_##inst[] = DT_INST_PROP(inst, short_codes); \
)); \
static const uint16_t longpress_long_codes_##inst[] = DT_INST_PROP(inst, long_codes); \
static const struct longpress_config longpress_config_##inst = { \
.input_dev = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, input)), \
.input_codes = longpress_input_codes_##inst, \
IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, short_codes), ( \
.short_codes = longpress_short_codes_##inst, \
)) \
.long_codes = longpress_long_codes_##inst, \
.num_codes = DT_INST_PROP_LEN(inst, input_codes), \
.long_delays_ms = DT_INST_PROP(inst, long_delay_ms), \
Expand Down
8 changes: 8 additions & 0 deletions tests/subsys/input/longpress/boards/native_sim.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@
long-codes = <INPUT_KEY_X>, <INPUT_KEY_Y>;
long-delay-ms = <100>;
};

longpress_no_short: longpress-no-short {
input = <&fake_input_device>;
compatible = "zephyr,input-longpress";
input-codes = <INPUT_KEY_0>, <INPUT_KEY_1>;
long-codes = <INPUT_KEY_X>, <INPUT_KEY_Y>;
long-delay-ms = <100>;
};
};
34 changes: 34 additions & 0 deletions tests/subsys/input/longpress/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ static const struct device *const fake_dev = DEVICE_DT_GET(
DT_NODELABEL(fake_input_device));
static const struct device *const longpress_dev = DEVICE_DT_GET(
DT_NODELABEL(longpress));
static const struct device *const longpress_no_short_dev = DEVICE_DT_GET(
DT_NODELABEL(longpress_no_short));

DEVICE_DT_DEFINE(DT_INST(0, vnd_input_device), NULL, NULL, NULL, NULL,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
Expand All @@ -30,6 +32,18 @@ static void test_cb(struct input_event *evt)
}
INPUT_CALLBACK_DEFINE(longpress_dev, test_cb);

static int event_count_no_short;
static struct input_event last_events_no_short[2];
static void test_cb_no_short(struct input_event *evt)
{
TC_PRINT("%s: %d %x %d\n", __func__, event_count_no_short, evt->code, evt->value);

event_count_no_short++;
memcpy(&last_events_no_short[1], &last_events_no_short[0], sizeof(struct input_event));
memcpy(&last_events_no_short[0], evt, sizeof(struct input_event));
}
INPUT_CALLBACK_DEFINE(longpress_no_short_dev, test_cb_no_short);

ZTEST(longpress, test_longpress_test)
{
zassert_equal(event_count, 0);
Expand All @@ -38,9 +52,11 @@ ZTEST(longpress, test_longpress_test)
input_report_key(fake_dev, INPUT_KEY_3, 1, true, K_FOREVER);
input_report_key(fake_dev, INPUT_KEY_3, 0, true, K_FOREVER);
zassert_equal(event_count, 0);
zassert_equal(event_count_no_short, 0);
input_report_abs(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
input_report_abs(fake_dev, INPUT_KEY_0, 0, true, K_FOREVER);
zassert_equal(event_count, 0);
zassert_equal(event_count_no_short, 0);

/* short press */
input_report_key(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
Expand All @@ -53,6 +69,7 @@ ZTEST(longpress, test_longpress_test)
zassert_equal(last_events[0].type, INPUT_EV_KEY);
zassert_equal(last_events[0].code, INPUT_KEY_A);
zassert_equal(last_events[0].value, 0);
zassert_equal(event_count_no_short, 0);

/* short press - other key */
input_report_key(fake_dev, INPUT_KEY_1, 1, true, K_FOREVER);
Expand All @@ -65,6 +82,7 @@ ZTEST(longpress, test_longpress_test)
zassert_equal(last_events[0].type, INPUT_EV_KEY);
zassert_equal(last_events[0].code, INPUT_KEY_B);
zassert_equal(last_events[0].value, 0);
zassert_equal(event_count_no_short, 0);

/* long press */
input_report_key(fake_dev, INPUT_KEY_0, 1, true, K_FOREVER);
Expand All @@ -78,6 +96,14 @@ ZTEST(longpress, test_longpress_test)
zassert_equal(last_events[0].code, INPUT_KEY_X);
zassert_equal(last_events[0].value, 0);

zassert_equal(event_count_no_short, 2);
zassert_equal(last_events_no_short[1].type, INPUT_EV_KEY);
zassert_equal(last_events_no_short[1].code, INPUT_KEY_X);
zassert_equal(last_events_no_short[1].value, 1);
zassert_equal(last_events_no_short[0].type, INPUT_EV_KEY);
zassert_equal(last_events_no_short[0].code, INPUT_KEY_X);
zassert_equal(last_events_no_short[0].value, 0);

/* long press - other key */
input_report_key(fake_dev, INPUT_KEY_1, 1, true, K_FOREVER);
k_sleep(K_MSEC(150));
Expand All @@ -89,6 +115,14 @@ ZTEST(longpress, test_longpress_test)
zassert_equal(last_events[0].type, INPUT_EV_KEY);
zassert_equal(last_events[0].code, INPUT_KEY_Y);
zassert_equal(last_events[0].value, 0);

zassert_equal(event_count_no_short, 4);
zassert_equal(last_events_no_short[1].type, INPUT_EV_KEY);
zassert_equal(last_events_no_short[1].code, INPUT_KEY_Y);
zassert_equal(last_events_no_short[1].value, 1);
zassert_equal(last_events_no_short[0].type, INPUT_EV_KEY);
zassert_equal(last_events_no_short[0].code, INPUT_KEY_Y);
zassert_equal(last_events_no_short[0].value, 0);
}

ZTEST_SUITE(longpress, NULL, NULL, NULL, NULL, NULL);

0 comments on commit eeb6bf7

Please sign in to comment.