Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add long-press navigation mode #440

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ target/*/tools/mkheader
cscope.*
ncscope.*

# clangd
.cache
compile_commands.json
10 changes: 10 additions & 0 deletions Documentation/dt-bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ them in the device node and lk2nd will use them instead of autodetecting.
qcom,board-id = <0xCE08FF01 1>;
```

### Single-key navigation

On some devices, such as smartwatches, there is only one key available for
navigation. In this case `lk2nd,single-key-navigation` property can be
used to switch the navigation scheme to short/long press of a single key.

```
lk2nd,single-key-navigation;
```

## Additional drivers

lk2nd provides a set of optional nodes, following a simple driver
Expand Down
4 changes: 4 additions & 0 deletions lk2nd/device/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ static void parse_dtb(const void *dtb)
if (len < 0)
dprintf(CRITICAL, "Failed to read 'lk2nd,dtb-files': %d\n", len);

val = fdt_getprop(dtb, node, "lk2nd,single-key-navigation", &len);
if (len >= 0)
lk2nd_dev.single_key = true;

dprintf(INFO, "Detected device: %s (compatible: %s)\n",
lk2nd_dev.model, lk2nd_dev.compatible);

Expand Down
3 changes: 3 additions & 0 deletions lk2nd/device/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#ifndef LK2ND_DEVICE_DEVICE_H
#define LK2ND_DEVICE_DEVICE_H

#include <stdbool.h>

struct lk2nd_panel {
const char *name;
const char *old_compatible;
Expand All @@ -23,6 +25,7 @@ struct lk2nd_device {
const char *battery;

const char *const *dtbfiles;
bool single_key;

struct lk2nd_panel panel;

Expand Down
1 change: 1 addition & 0 deletions lk2nd/device/dts/msm8226/apq8026-asus-sparrow.dts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
model = "ASUS ZenWatch 2";
compatible = "asus,sparrow";

lk2nd,single-key-navigation;
lk2nd,dtb-files = "apq8026-asus-sparrow";
};
1 change: 1 addition & 0 deletions lk2nd/device/dts/msm8226/apq8026-huawei-sturgeon.dts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
model = "Huawei Watch";
compatible = "huawei,sturgeon";

lk2nd,single-key-navigation;
lk2nd,dtb-files = "apq8026-huawei-sturgeon";

gpio-keys {
Expand Down
1 change: 1 addition & 0 deletions lk2nd/device/dts/msm8226/apq8026-lg-lenok.dts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
model = "LG G Watch R";
compatible = "lg,lenok";

lk2nd,single-key-navigation;
lk2nd,dtb-files = "apq8026-lg-lenok";
};

25 changes: 22 additions & 3 deletions lk2nd/device/menu/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,30 @@ static uint16_t lk2nd_boot_pressed_key(void)
return 0;
}

#define LONG_PRESS_DURATION 1000

static uint16_t wait_key(void)
{
uint16_t keycode = 0;
int press_start = 0;
int press_duration;

while (!(keycode = lk2nd_boot_pressed_key()))
thread_sleep(1);

while (lk2nd_keys_pressed(keycode))
press_start = current_time();

while (lk2nd_keys_pressed(keycode)) {
thread_sleep(1);

press_duration = current_time() - press_start;
if (lk2nd_dev.single_key && press_duration > LONG_PRESS_DURATION)
return KEY_POWER;
}

if (lk2nd_dev.single_key)
keycode = KEY_VOLUMEDOWN;

/* A small debounce delay */
thread_sleep(5);

Expand Down Expand Up @@ -180,8 +194,13 @@ void display_fastboot_menu(void)
y_menu = y;
y += incr * (ARRAY_SIZE(menu_options) + 1);

fbcon_puts_ln(SILVER, y, incr, true, "Volume keys to navigate.");
fbcon_puts_ln(SILVER, y, incr, true, "Power key to select.");
if (lk2nd_dev.single_key) {
fbcon_puts_ln(SILVER, y, incr, true, "Short press to navigate.");
fbcon_puts_ln(SILVER, y, incr, true, "Long press to select.");
} else {
fbcon_puts_ln(SILVER, y, incr, true, "Volume keys to navigate.");
fbcon_puts_ln(SILVER, y, incr, true, "Power key to select.");
}

/*
* Draw the device-specific information at the bottom of the screen
Expand Down