Lakka: add menu for time zone setting

This adds new entry under Settings -> Services (where all Lakka related
services are currently available, such as switches for services like
SSH, Samba, etc.). By adding this the users do not have to use the
command line / access the file system directly to change their local
time zone to adjust the date/time displayed in RetroArch.
This commit is contained in:
Tomáš Kelemen (vudiq) 2021-04-17 23:54:45 +02:00
parent 0ddfbd976c
commit 90529c62b2
13 changed files with 164 additions and 0 deletions

View File

@ -1185,6 +1185,47 @@ const char *config_get_midi_driver_options(void)
return char_list_new_special(STRING_LIST_MIDI_DRIVERS, NULL); return char_list_new_special(STRING_LIST_MIDI_DRIVERS, NULL);
} }
#ifdef HAVE_LAKKA
void config_set_timezone(char *timezone)
{
setenv("TZ", timezone, 1);
tzset();
}
const char *config_get_all_timezones(void)
{
return char_list_new_special(STRING_LIST_TIMEZONES, NULL);
}
static void load_timezone(char *setting)
{
char haystack[TIMEZONE_LENGTH+32];
static char *needle = "TIMEZONE=";
size_t needle_len = strlen(needle);
RFILE *tzfp = filestream_open(LAKKA_TIMEZONE_PATH,
RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (tzfp != NULL)
{
filestream_gets(tzfp, haystack, sizeof(haystack)-1);
filestream_close(tzfp);
char *start = strstr(haystack, needle);
if (start != NULL)
snprintf(setting, TIMEZONE_LENGTH, "%s", start + needle_len);
else
snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
}
else
snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
config_set_timezone(setting);
}
#endif
bool config_overlay_enable_default(void) bool config_overlay_enable_default(void)
{ {
if (g_defaults.overlay_set) if (g_defaults.overlay_set)
@ -2347,6 +2388,7 @@ void config_set_defaults(void *data)
configuration_set_bool(settings, configuration_set_bool(settings,
settings->bools.bluetooth_enable, filestream_exists(LAKKA_BLUETOOTH_PATH)); settings->bools.bluetooth_enable, filestream_exists(LAKKA_BLUETOOTH_PATH));
configuration_set_bool(settings, settings->bools.localap_enable, false); configuration_set_bool(settings, settings->bools.localap_enable, false);
load_timezone(settings->arrays.timezone);
#endif #endif
#ifdef HAVE_MENU #ifdef HAVE_MENU

View File

@ -29,6 +29,10 @@
#include "input/input_defines.h" #include "input/input_defines.h"
#include "led/led_defines.h" #include "led/led_defines.h"
#ifdef HAVE_LAKKA
#include "lakka.h"
#endif
#define configuration_set_float(settings, var, newvar) \ #define configuration_set_float(settings, var, newvar) \
{ \ { \
settings->modified = true; \ settings->modified = true; \
@ -381,6 +385,9 @@ typedef struct settings
char ai_service_url[PATH_MAX_LENGTH]; char ai_service_url[PATH_MAX_LENGTH];
char crt_switch_timings[255]; char crt_switch_timings[255];
#ifdef HAVE_LAKKA
char timezone[TIMEZONE_LENGTH];
#endif
} arrays; } arrays;
struct struct
@ -1011,6 +1018,11 @@ void config_save_file_salamander(void);
settings_t *config_get_ptr(void); settings_t *config_get_ptr(void);
#ifdef HAVE_LAKKA
const char *config_get_all_timezones(void);
void config_set_timezone(char *timezone);
#endif
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -195,6 +195,10 @@ MSG_HASH(
MENU_ENUM_LABEL_BLUETOOTH_ENABLE, MENU_ENUM_LABEL_BLUETOOTH_ENABLE,
"bluetooth_enable" "bluetooth_enable"
) )
MSG_HASH(
MENU_ENUM_LABEL_TIMEZONE,
"timezone"
)
#endif #endif
MSG_HASH( MSG_HASH(
MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL, MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL,

View File

@ -2289,6 +2289,15 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len, snprintf(s, len,
"MIDI driver to use."); "MIDI driver to use.");
break; break;
#ifdef HAVE_LAKKA
case MENU_ENUM_LABEL_TIMEZONE:
snprintf(s, len,
"Displays a list of available timezones. After\n"
"selecting a time zone, time and date is adjusted\n"
"to the selected time zone. It assumes, that system/\n"
"hardware clock is set to UTC.");
break;
#endif
case MENU_ENUM_LABEL_MIDI_INPUT: case MENU_ENUM_LABEL_MIDI_INPUT:
snprintf(s, len, snprintf(s, len,
"Sets the input device (driver specific).\n" "Sets the input device (driver specific).\n"

View File

@ -12218,6 +12218,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_LOCALAP_ENABLE, MENU_ENUM_SUBLABEL_LOCALAP_ENABLE,
"Enable or disable Wi-Fi Access Point." "Enable or disable Wi-Fi Access Point."
) )
MSG_HASH(
MENU_ENUM_LABEL_VALUE_TIMEZONE,
"Time zone"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_TIMEZONE,
"Select your time zone to adjust the date and time to your location."
)
MSG_HASH( MSG_HASH(
MSG_LOCALAP_SWITCHING_OFF, MSG_LOCALAP_SWITCHING_OFF,
"Switching off Wi-Fi Access Point." "Switching off Wi-Fi Access Point."

View File

@ -24,6 +24,10 @@
#define LAKKA_UPDATE_DIR "/storage/.update/" #define LAKKA_UPDATE_DIR "/storage/.update/"
#define LAKKA_CONNMAN_DIR "/storage/.cache/connman/" #define LAKKA_CONNMAN_DIR "/storage/.cache/connman/"
#define LAKKA_LOCALAP_PATH "/storage/.cache/services/localap.conf" #define LAKKA_LOCALAP_PATH "/storage/.cache/services/localap.conf"
#define LAKKA_TIMEZONE_PATH "/storage/.cache/timezone"
#define DEFAULT_TIMEZONE "UTC"
#define TIMEZONE_LENGTH 255
#include "switch_performance_profiles.h" #include "switch_performance_profiles.h"

View File

@ -56,6 +56,9 @@ enum string_list_type
STRING_LIST_RECORD_DRIVERS, STRING_LIST_RECORD_DRIVERS,
STRING_LIST_MIDI_DRIVERS, STRING_LIST_MIDI_DRIVERS,
STRING_LIST_SUPPORTED_CORES_PATHS, STRING_LIST_SUPPORTED_CORES_PATHS,
#ifdef HAVE_LAKKA
STRING_LIST_TIMEZONES,
#endif
STRING_LIST_SUPPORTED_CORES_NAMES STRING_LIST_SUPPORTED_CORES_NAMES
}; };

View File

@ -1572,6 +1572,9 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
case MENU_ENUM_LABEL_BLUETOOTH_DRIVER: case MENU_ENUM_LABEL_BLUETOOTH_DRIVER:
case MENU_ENUM_LABEL_WIFI_DRIVER: case MENU_ENUM_LABEL_WIFI_DRIVER:
case MENU_ENUM_LABEL_MENU_DRIVER: case MENU_ENUM_LABEL_MENU_DRIVER:
#ifdef HAVE_LAKKA
case MENU_ENUM_LABEL_TIMEZONE:
#endif
BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label); BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label);
break; break;
case MENU_ENUM_LABEL_CONNECT_BLUETOOTH: case MENU_ENUM_LABEL_CONNECT_BLUETOOTH:

View File

@ -227,6 +227,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_ssh_enable, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_samba_enable, MENU_ENUM_SUBLABEL_SAMBA_ENABLE ) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_samba_enable, MENU_ENUM_SUBLABEL_SAMBA_ENABLE )
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_bluetooth_enable, MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE ) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_bluetooth_enable, MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE )
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_localap_enable, MENU_ENUM_SUBLABEL_LOCALAP_ENABLE ) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_localap_enable, MENU_ENUM_SUBLABEL_LOCALAP_ENABLE )
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_timezone, MENU_ENUM_SUBLABEL_TIMEZONE)
#endif #endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_user_language, MENU_ENUM_SUBLABEL_USER_LANGUAGE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_user_language, MENU_ENUM_SUBLABEL_USER_LANGUAGE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_max_swapchain_images, MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES ) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_max_swapchain_images, MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES )
@ -3907,6 +3908,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_LOCALAP_ENABLE: case MENU_ENUM_LABEL_LOCALAP_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_localap_enable); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_localap_enable);
break; break;
case MENU_ENUM_LABEL_TIMEZONE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_timezone);
break;
#endif #endif
case MENU_ENUM_LABEL_USER_LANGUAGE: case MENU_ENUM_LABEL_USER_LANGUAGE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_user_language); BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_user_language);

View File

@ -7704,6 +7704,7 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_SAMBA_ENABLE, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_SAMBA_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_BLUETOOTH_ENABLE, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_BLUETOOTH_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_LOCALAP_ENABLE, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_LOCALAP_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_TIMEZONE, PARSE_ONLY_STRING_OPTIONS},
}; };
for (i = 0; i < ARRAY_SIZE(build_list); i++) for (i = 0; i < ARRAY_SIZE(build_list); i++)

View File

@ -7991,6 +7991,24 @@ static void localap_enable_toggle_change_handler(rarch_setting_t *setting)
driver_wifi_tether_start_stop(*setting->value.target.boolean, driver_wifi_tether_start_stop(*setting->value.target.boolean,
LAKKA_LOCALAP_PATH); LAKKA_LOCALAP_PATH);
} }
static void timezone_change_handler(rarch_setting_t *setting)
{
if (!setting)
return;
config_set_timezone(setting->value.target.string);
RFILE *tzfp = filestream_open(LAKKA_TIMEZONE_PATH,
RETRO_VFS_FILE_ACCESS_WRITE,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (tzfp != NULL)
{
filestream_printf(tzfp, "TIMEZONE=%s", setting->value.target.string);
filestream_close(tzfp);
}
}
#endif #endif
static bool setting_append_list_input_player_options( static bool setting_append_list_input_player_options(
@ -18539,6 +18557,23 @@ static bool setting_append_list(
SD_FLAG_NONE); SD_FLAG_NONE);
(*list)[list_info->index - 1].change_handler = localap_enable_toggle_change_handler; (*list)[list_info->index - 1].change_handler = localap_enable_toggle_change_handler;
CONFIG_STRING_OPTIONS(
list, list_info,
settings->arrays.timezone,
sizeof(settings->arrays.timezone),
MENU_ENUM_LABEL_TIMEZONE,
MENU_ENUM_LABEL_VALUE_TIMEZONE,
DEFAULT_TIMEZONE,
config_get_all_timezones(),
&group_info,
&subgroup_info,
parent_group,
general_read_handler,
general_write_handler);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_IS_DRIVER);
(*list)[list_info->index - 1].action_ok = setting_action_ok_mapped_string;
(*list)[list_info->index - 1].change_handler = timezone_change_handler;
END_SUB_GROUP(list, list_info, parent_group); END_SUB_GROUP(list, list_info, parent_group);
END_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group);
#endif #endif

View File

@ -1826,6 +1826,7 @@ enum msg_hash_enums
MENU_LABEL(SAMBA_ENABLE), MENU_LABEL(SAMBA_ENABLE),
MENU_LABEL(BLUETOOTH_ENABLE), MENU_LABEL(BLUETOOTH_ENABLE),
MENU_LABEL(LOCALAP_ENABLE), MENU_LABEL(LOCALAP_ENABLE),
MENU_LABEL(TIMEZONE),
#endif #endif
MENU_LABEL(NETPLAY_DELAY_FRAMES), MENU_LABEL(NETPLAY_DELAY_FRAMES),
MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE), MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE),

View File

@ -277,6 +277,10 @@
/* Forward declarations */ /* Forward declarations */
#include "retroarch_fwd_decls.h" #include "retroarch_fwd_decls.h"
#ifdef HAVE_LAKKA
#include "lakka.h"
#endif
/* GLOBAL POINTER GETTERS */ /* GLOBAL POINTER GETTERS */
#ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKING
@ -8722,6 +8726,40 @@ struct string_list *string_list_new_special(enum string_list_type type,
string_list_append(s, opt, attr); string_list_append(s, opt, attr);
} }
break; break;
#ifdef HAVE_LAKKA
case STRING_LIST_TIMEZONES:
{
const char *opt = DEFAULT_TIMEZONE;
*len += strlen(opt) + 1;
string_list_append(s, opt, attr);
FILE *zones_file = popen("grep -v ^# /usr/share/zoneinfo/zone.tab | "
"cut -f3 | "
"sort", "r");
if (zones_file != NULL)
{
char zone_desc[TIMEZONE_LENGTH];
while (fgets(zone_desc, TIMEZONE_LENGTH, zones_file))
{
size_t zone_desc_len = strlen(zone_desc);
if (zone_desc_len > 0)
if (zone_desc[--zone_desc_len] == '\n')
zone_desc[zone_desc_len] = '\0';
if (strlen(zone_desc) > 0)
{
const char *opt = zone_desc;
*len += strlen(opt) + 1;
string_list_append(s, opt, attr);
}
}
pclose(zones_file);
}
}
break;
#endif
case STRING_LIST_SUPPORTED_CORES_PATHS: case STRING_LIST_SUPPORTED_CORES_PATHS:
core_info_get_list(&core_info_list); core_info_get_list(&core_info_list);