From eebeaf77e1f110076dbdce08b6237ef3a14342bf Mon Sep 17 00:00:00 2001 From: Ningyuan Li Date: Tue, 30 Apr 2024 01:02:36 +0900 Subject: [PATCH] allows capture of webOS home key --- src/app/app.c | 4 ++++ src/app/app_settings.c | 3 +++ src/app/lvgl/input/lv_drv_sdl_key.c | 16 ++++++++++++---- src/app/platform/webos/app_webos.c | 6 ++++++ src/app/platform/webos/app_webos.h | 21 +++++++++++++++++++++ src/app/platform/webos/keyboard_webos.c | 9 ++++++++- src/app/stream/input/session_keyboard.c | 4 ++-- src/app/ui/settings/panes/input.pane.c | 3 +++ 8 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 src/app/platform/webos/app_webos.h diff --git a/src/app/app.c b/src/app/app.c index c5c944994..75849694f 100644 --- a/src/app/app.c +++ b/src/app/app.c @@ -68,6 +68,10 @@ int app_init(app_t *app, app_settings_loader *settings_loader, int argc, char *a SDL_SetHint(SDL_HINT_WEBOS_CURSOR_FREQUENCY, "60"); SDL_SetHint(SDL_HINT_WEBOS_CURSOR_CALIBRATION_DISABLE, "true"); SDL_SetHint(SDL_HINT_WEBOS_HIDAPI_IGNORE_BLUETOOTH_DEVICES, "0x057e/0x0000"); + if (app->settings.syskey_capture) { + SDL_SetHint(SDL_HINT_WEBOS_ACCESS_POLICY_KEYS_HOME, "true"); + SDL_SetHint(SDL_HINT_WEBOS_ACCESS_POLICY_RIBBON, "false"); + } #endif // DO not init video subsystem before NDL/LGNC initialization if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { diff --git a/src/app/app_settings.c b/src/app/app_settings.c index 87ff89d78..90e4128ee 100644 --- a/src/app/app_settings.c +++ b/src/app/app_settings.c @@ -116,6 +116,7 @@ bool settings_save(app_settings_t *config) { #endif ini_write_bool(fp, "swap_abxy", config->swap_abxy); ini_write_int(fp, "stick_deadzone", config->stick_deadzone); + ini_write_bool(fp, "syskey_capture", config->syskey_capture); ini_write_section(fp, "video"); ini_write_string(fp, "decoder", config->decoder); @@ -265,6 +266,8 @@ static int settings_parse(app_settings_t *config, const char *section, const cha } } else if (INI_NAME_MATCH("swap_abxy")) { config->swap_abxy = INI_IS_TRUE(value); + } else if (INI_NAME_MATCH("syskey_capture")) { + config->syskey_capture = INI_IS_TRUE(value); } else if (INI_FULL_MATCH("video", "decoder")) { set_string(&config->decoder, value); } else if (INI_FULL_MATCH("audio", "backend")) { diff --git a/src/app/lvgl/input/lv_drv_sdl_key.c b/src/app/lvgl/input/lv_drv_sdl_key.c index 0f8fc8e4d..44097a71d 100644 --- a/src/app/lvgl/input/lv_drv_sdl_key.c +++ b/src/app/lvgl/input/lv_drv_sdl_key.c @@ -9,18 +9,20 @@ #include "lv_drv_sdl_key.h" #include "stream/session_events.h" -static bool read_event(const SDL_Event *event, lv_drv_sdl_key_t *state); - -static bool read_keyboard(app_ui_input_t *input, const SDL_KeyboardEvent *event, lv_drv_sdl_key_t *state); - #if TARGET_WEBOS +#include "platform/webos/app_webos.h" + static bool read_webos_key(app_ui_input_t *input, const SDL_KeyboardEvent *event, lv_drv_sdl_key_t *state); static void webos_key_input_mode(app_ui_input_t *input, const SDL_KeyboardEvent *event); #endif +static bool read_event(const SDL_Event *event, lv_drv_sdl_key_t *state); + +static bool read_keyboard(app_ui_input_t *input, const SDL_KeyboardEvent *event, lv_drv_sdl_key_t *state); + static void sdl_input_read(lv_indev_drv_t *drv, lv_indev_data_t *data); int lv_sdl_init_key_input(lv_drv_sdl_key_t *drv, app_ui_input_t *input) { @@ -218,8 +220,14 @@ static bool read_webos_key(app_ui_input_t *input, const SDL_KeyboardEvent *event if (app->session == NULL) { app_request_exit(); } + return false; } + case SDL_SCANCODE_WEBOS_HOME: { + if (app->session == NULL) { + app_webos_open_ribbon(); + } return false; + } case SDL_SCANCODE_WEBOS_RED: case SDL_SCANCODE_WEBOS_GREEN: case SDL_SCANCODE_WEBOS_YELLOW: diff --git a/src/app/platform/webos/app_webos.c b/src/app/platform/webos/app_webos.c index 35d1bed50..13fbb2a14 100644 --- a/src/app/platform/webos/app_webos.c +++ b/src/app/platform/webos/app_webos.c @@ -1,4 +1,5 @@ #include "app.h" +#include "app_webos.h" #include "app_launch.h" #include @@ -79,4 +80,9 @@ app_launch_params_t *app_handle_launch(app_t *app, int argc, char *argv[]) { } jdomparser_release(&parser); return params; +} + +void app_webos_open_ribbon() { + static const char *payload = "{\"id\":\"com.webos.app.home\",\"params\":{\"launchType\":\"homeKey\"}}"; + HLunaServiceCallSync("luna://com.webos.applicationManager/launch", payload, true, NULL); } \ No newline at end of file diff --git a/src/app/platform/webos/app_webos.h b/src/app/platform/webos/app_webos.h new file mode 100644 index 000000000..19d9f7325 --- /dev/null +++ b/src/app/platform/webos/app_webos.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +void app_webos_open_ribbon(); \ No newline at end of file diff --git a/src/app/platform/webos/keyboard_webos.c b/src/app/platform/webos/keyboard_webos.c index a39447e35..a74ddbfcf 100644 --- a/src/app/platform/webos/keyboard_webos.c +++ b/src/app/platform/webos/keyboard_webos.c @@ -13,10 +13,11 @@ #include "util/bus.h" #include "util/user_event.h" #include "logging.h" +#include "app_webos.h" #define TV_REMOTE_TOGGLE_SOFT_INPUT 0 -bool webos_intercept_remote_keys(stream_input_t *input, const SDL_KeyboardEvent *event, short *keyCode) { +bool stream_input_webos_intercept_remote_keys(stream_input_t *input, const SDL_KeyboardEvent *event, short *keyCode) { session_t *session = input->session; app_t *app = session->app; switch ((unsigned int) event->keysym.scancode) { @@ -26,6 +27,12 @@ bool webos_intercept_remote_keys(stream_input_t *input, const SDL_KeyboardEvent } return true; } + case SDL_SCANCODE_WEBOS_HOME: { + if (event->state == SDL_RELEASED) { + app_webos_open_ribbon(); + } + return true; + } case SDL_SCANCODE_WEBOS_BACK: *keyCode = VK_ESCAPE /* SDL_SCANCODE_ESCAPE */; return false; diff --git a/src/app/stream/input/session_keyboard.c b/src/app/stream/input/session_keyboard.c index 2aa7e2fb3..17ed5793a 100644 --- a/src/app/stream/input/session_keyboard.c +++ b/src/app/stream/input/session_keyboard.c @@ -66,7 +66,7 @@ static int keydown_count = 0; #if TARGET_WEBOS -bool webos_intercept_remote_keys(stream_input_t *input, const SDL_KeyboardEvent *event, short *keyCode); +bool stream_input_webos_intercept_remote_keys(stream_input_t *input, const SDL_KeyboardEvent *event, short *keyCode); #endif @@ -128,7 +128,7 @@ void performPendingSpecialKeyCombo(stream_input_t *input) { void stream_input_handle_key(stream_input_t *input, const SDL_KeyboardEvent *event) { short keyCode = 0; #if TARGET_WEBOS - if (webos_intercept_remote_keys(input, event, &keyCode)) { + if (stream_input_webos_intercept_remote_keys(input, event, &keyCode)) { return; } #endif diff --git a/src/app/ui/settings/panes/input.pane.c b/src/app/ui/settings/panes/input.pane.c index 23e226ea9..68f9be894 100644 --- a/src/app/ui/settings/panes/input.pane.c +++ b/src/app/ui/settings/panes/input.pane.c @@ -46,6 +46,9 @@ static lv_obj_t *create_obj(lv_fragment_t *self, lv_obj_t *container) { pref_checkbox(view, locstr("View-only mode"), &app_configuration->viewonly, false); pref_desc_label(view, locstr("Don't send mouse, keyboard or gamepad input to host computer."), false); + pref_checkbox(view, locstr("Capture system keys"), &app_configuration->syskey_capture, false); + pref_desc_label(view, locstr("Capture and send system keys (e.g. Meta/Win key) to host computer."), false); + pref_header(view, locstr("Mouse")); #if FEATURE_INPUT_EVMOUSE