From 3ac949482123e72913414b36901f4cb5fe00af4b Mon Sep 17 00:00:00 2001 From: Dylan Van Assche Date: Fri, 1 Jan 2021 18:46:22 +0100 Subject: [PATCH] fbd-feedback-manager: Allow device-specific feedbackd themes Reads the compatible list of the device and tries to find a device-specific theme file in all directories. If no configuration is found, we fall back to a default theme file. The device-specific theme file can always be overriden by specifying the FEEDBACK_THEME environment variable --- src/fbd-feedback-manager.c | 61 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index ef508c7..3804f89 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -21,10 +21,14 @@ #define FEEDBACKD_SCHEMA_ID "org.sigxcpu.feedbackd" #define FEEDBACKD_KEY_PROFILE "profile" +#define FEEDBACKD_THEME_VAR "FEEDBACK_THEME" #define APP_SCHEMA FEEDBACKD_SCHEMA_ID ".application" #define APP_PREFIX "/org/sigxcpu/feedbackd/application/" +#define DEVICE_TREE_PATH "/sys/firmware/devicetree/base/compatible" +#define DEVICE_NAME_MAX 1024 + /** * SECTION:fbd-feedback-manager @@ -352,6 +356,51 @@ fbd_feedback_manager_handle_end_feedback (LfbGdbusFeedback *object, return TRUE; } +static const gchar * +find_themefile (void) { + gint i = 0; + gsize len; + const gchar *comp; + g_autoptr(GError) err = NULL; + gchar **xdg_data_dirs = (gchar **) g_get_system_data_dirs(); + g_autofree gchar *config_path = NULL; + g_autofree gchar *compatibles = NULL; + + // Try to read the device name + if (g_file_test(DEVICE_TREE_PATH, (G_FILE_TEST_EXISTS))) { + g_debug("Found device tree device compatible at %s", DEVICE_TREE_PATH); + + // Check if feedbackd has a proper config available this device + if(!g_file_get_contents(DEVICE_TREE_PATH, &compatibles, &len, &err)) + g_warning ("Unable to read: %s", err->message); + + comp = compatibles; + while(comp - compatibles < len) { + + // Iterate over $XDG_DATA_DIRS + for (i = 0; i < g_strv_length(xdg_data_dirs); i++) { + config_path = g_strconcat(xdg_data_dirs[i], "feedbackd/themes/", comp, ".json", NULL); + g_debug("Searching for device specific themefile in %s", config_path); + + // Check if file exist + if (g_file_test(config_path, (G_FILE_TEST_EXISTS))) { + g_debug("Found themefile for this device at: %s", config_path); + return g_strdup(config_path); + } + } + + // Next compatible + comp = strchr(comp, 0); + comp++; + } + } + else { + g_debug("Device tree path does not exist: %s", DEVICE_TREE_PATH); + } + + return NULL; +} + static void fbd_feedback_manager_constructed (GObject *object) { @@ -361,14 +410,22 @@ fbd_feedback_manager_constructed (GObject *object) G_OBJECT_CLASS (fbd_feedback_manager_parent_class)->constructed (object); - themefile = g_getenv ("FEEDBACK_THEME"); + // Overide themefile with environment variable if requested + themefile = g_getenv(FEEDBACKD_THEME_VAR); + + // Search for device-specific configuration + if (!themefile) + themefile = find_themefile (); + + // Fallback to default configuration if needed if (!themefile) themefile = FEEDBACKD_THEME_DIR "/default.json"; + g_info("Using themefile: %s", themefile); self->theme = fbd_feedback_theme_new_from_file (themefile, &err); if (!self->theme) { /* No point to carry on */ - g_error ("Failed to load default theme: %s", err->message); + g_error ("Failed to load theme: %s", err->message); } g_signal_connect (self, "notify::profile", (GCallback)on_profile_changed, NULL);