diff --git a/README.md b/README.md index ef32aff..91067d7 100644 --- a/README.md +++ b/README.md @@ -181,12 +181,7 @@ examples: over `/usr/share/feedbackd/themes/pine64-pinephone-1.2.json` - etc... -The currently available feedback types are: - -- Sound (an audible sound from the sound naming spec) -- VibraRumble: haptic motor rumbling -- VibraPeriodic: periodic feedback from the haptic motor -- Led: Feedback via blinking LEDs +For available feeddback types see the [feedback-themes][](5) manpage. You can check the feedback theme and the classes (prefixed with Fbd) for available properties. Note that the feedback theme API (including @@ -271,3 +266,4 @@ GSETTINGS_SCHEMA_DIR=_build/data/ gsettings set org.sigxcpu.feedbackd.applicatio [debian/control]: ./debian/control#L5 [1]: https://source.puri.sm/Librem5/feedbackd-device-themes +[feedback-themes]: ./doc/feedback-themes.rst diff --git a/data/default.json b/data/default.json index 40e5858..521bf4e 100644 --- a/data/default.json +++ b/data/default.json @@ -171,13 +171,13 @@ { "event-name" : "phone-missed-call", "type" : "Led", - "color" : "blue", + "color" : "#00FFFF", "frequency" : 3000 }, { "event-name" : "message-missed-email", "type" : "Led", - "color" : "blue", + "color" : "#800080", "frequency" : 2000 }, { diff --git a/doc/feedback-themes.rst b/doc/feedback-themes.rst index 203f550..dea3682 100644 --- a/doc/feedback-themes.rst +++ b/doc/feedback-themes.rst @@ -9,21 +9,49 @@ Theme configuration for feedbackd --------------------------------- DESCRIPTION -=========== +----------- In order to reflect device specifics and user overrides the feedback (such as sound, haptic or led) that is being triggered by an event can be configured and overridden by so called themes. Feedback themes use a JSON format that can be validated with ``fbd-theme-validate``. -For details on how to create or modify feedback themes see [feedbackd's documentation]( -https://source.puri.sm/Librem5/feedbackd#feedback-theme). +For details on how to create or modify feedback themes see +``feedbackd's documentation`` at https://source.puri.sm/Librem5/feedbackd#feedback-theme + +Feedback types +-------------- + +To build a theme you can use several different feedback types: + +- `Sound`: Plays a sound from the installed sound theme +- `VibraRumble`: A single rumble using the haptic motor +- `VibraPeriodic`: A periodic rumble using the haptic motor +- `Led`: A LED blinking in a periodic pattern Sound feedback -============== +~~~~~~~~~~~~~~ Sound feedbacks specify an event name from a XDG sound theme. Sound themes -are described in the [Sound theme spec](https://freedesktop.org/wiki/Specifications/sound-theme-spec/). +are described in the ``Sound theme spec`` at https://freedesktop.org/wiki/Specifications/sound-theme-spec/ + +VibraRumble feedback +~~~~~~~~~~~~~~~~~~~~ + +The `VibraRumble` feedback uses a single property + +- `duration`: The duration of the rumble in ms. + +LED feedback +~~~~~~~~~~~~ + +The `Led` feedback type uses two properties to specify the way a LED blinks. + +- `color`: This specifies the color a LED should blink with. It supports the fixed color names `red`, + `green`, `blue` and `white` as well as values in the RGB HEX format (`#RRGGBB`) where + `RR`, `GG` and `BB` are two digit hex value between `00` and `FF` specifying the value of + each component. E.g. `#00FFFF` corresponds to cyan color. +- `frequency`: The LEDs blinkinig frequencey in mHz. See also ======== diff --git a/src/fbd-dev-led-multicolor.c b/src/fbd-dev-led-multicolor.c index 23fcf54..e330155 100644 --- a/src/fbd-dev-led-multicolor.c +++ b/src/fbd-dev-led-multicolor.c @@ -91,7 +91,8 @@ fbd_dev_led_multicolor_probe (FbdDevLed *led, GError **error) static gboolean fbd_dev_led_multicolor_set_color (FbdDevLed *led, - FbdFeedbackLedColor color) + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb) { FbdDevLedMulticolor *self = FBD_DEV_LED_MULTICOLOR (led); FbdDevLedMulticolorPrivate *priv = fbd_dev_led_multicolor_get_instance_private (self); @@ -124,12 +125,19 @@ fbd_dev_led_multicolor_set_color (FbdDevLed *led, colors[priv->green_index] = 0; colors[priv->blue_index] = max_brightness; break; + case FBD_FEEDBACK_LED_COLOR_RGB: + colors[priv->red_index] = rgb->r; + colors[priv->green_index] = rgb->g; + colors[priv->blue_index] = rgb->b; + break; default: g_warning("Unhandled color: %d\n", color); return FALSE; } - intensity = g_strdup_printf ("%d %d %d\n", colors[0], colors[1], colors[2]); + intensity = g_strdup_printf ("%u %u %u\n", colors[0], colors[1], colors[2]); + g_debug ("Multicolor intensity: %s", intensity); + fbd_dev_led_set_brightness (led, max_brightness); success = fbd_udev_set_sysfs_path_attr_as_string (dev, LED_MULTI_INTENSITY_ATTR, @@ -157,6 +165,8 @@ fbd_dev_led_multicolor_supports_color (FbdDevLed *led, return TRUE; case FBD_FEEDBACK_LED_COLOR_BLUE: return TRUE; + case FBD_FEEDBACK_LED_COLOR_RGB: + return TRUE; default: g_warning ("Color unsupported: %d", color); return FALSE; diff --git a/src/fbd-dev-led.c b/src/fbd-dev-led.c index f3b942f..1ec0812 100644 --- a/src/fbd-dev-led.c +++ b/src/fbd-dev-led.c @@ -33,10 +33,7 @@ static GParamSpec *props[PROP_LAST_PROP]; typedef struct _FbdDevLedPrivate { GUdevDevice *dev; guint max_brightness; - /* - * We just use the colors from the feedback until we - * do rgb mixing, etc - */ + FbdFeedbackLedColor color; } FbdDevLedPrivate; @@ -55,9 +52,6 @@ fbd_dev_led_probe_default (FbdDevLed *led, GError **error) gboolean success = FALSE; name = g_udev_device_get_name (priv->dev); - /* We don't know anything about diffusors that can combine different - color LEDSs so go with fixed colors until the kernel gives us - enough information */ for (int i = 0; i <= FBD_FEEDBACK_LED_COLOR_LAST; i++) { g_autofree char *color = NULL; g_autofree char *enum_name = NULL; @@ -94,7 +88,8 @@ fbd_dev_led_probe_default (FbdDevLed *led, GError **error) static gboolean fbd_dev_led_set_color_default (FbdDevLed *led, - FbdFeedbackLedColor color) + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb) { /* Ignore setting color as we have a single color only */ return TRUE; @@ -270,9 +265,9 @@ fbd_dev_led_set_brightness (FbdDevLed *led, guint brightness) gboolean -fbd_dev_led_start_periodic (FbdDevLed *led, - guint max_brightness_percentage, - guint freq) +fbd_dev_led_start_periodic (FbdDevLed *led, + guint max_brightness_percentage, + guint freq) { FbdDevLedClass *fbd_dev_led_class = FBD_DEV_LED_GET_CLASS (led); @@ -283,14 +278,15 @@ fbd_dev_led_start_periodic (FbdDevLed *led, gboolean -fbd_dev_led_set_color (FbdDevLed *led, - FbdFeedbackLedColor color) +fbd_dev_led_set_color (FbdDevLed *led, + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb) { FbdDevLedClass *fbd_dev_led_class = FBD_DEV_LED_GET_CLASS (led); g_return_val_if_fail (FBD_IS_DEV_LED (led), FALSE); - return fbd_dev_led_class->set_color (led, color); + return fbd_dev_led_class->set_color (led, color, rgb); } diff --git a/src/fbd-dev-led.h b/src/fbd-dev-led.h index 0aba548..0122ecd 100644 --- a/src/fbd-dev-led.h +++ b/src/fbd-dev-led.h @@ -20,10 +20,12 @@ G_DECLARE_DERIVABLE_TYPE (FbdDevLed, fbd_dev_led, FBD, DEV_LED, GObject) FbdDevLed *fbd_dev_led_new (GUdevDevice *dev, GError **err); gboolean fbd_dev_led_set_brightness (FbdDevLed *led, guint brightness); guint fbd_dev_led_get_max_brightness (FbdDevLed *led); -gboolean fbd_dev_led_set_color (FbdDevLed *led, FbdFeedbackLedColor color); -gboolean fbd_dev_led_start_periodic (FbdDevLed *led, - guint max_brightness_percentage, - guint freq); +gboolean fbd_dev_led_set_color (FbdDevLed *led, + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb); +gboolean fbd_dev_led_start_periodic (FbdDevLed *led, + guint max_brightness_percentage, + guint freq); gboolean fbd_dev_led_supports_color (FbdDevLed *led, FbdFeedbackLedColor color); struct _FbdDevLedClass { @@ -34,7 +36,8 @@ struct _FbdDevLedClass { guint max_brightness_percentage, guint freq); gboolean (*set_color) (FbdDevLed *led, - FbdFeedbackLedColor color); + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb); gboolean (*supports_color) (FbdDevLed *led, FbdFeedbackLedColor color); }; diff --git a/src/fbd-dev-leds.c b/src/fbd-dev-leds.c index 418cf44..f0eb1df 100644 --- a/src/fbd-dev-leds.c +++ b/src/fbd-dev-leds.c @@ -180,15 +180,19 @@ fbd_dev_leds_new (GError **error) /** * fbd_dev_leds_start_periodic: * @self: The #FbdDevLeds - * @color: The color to use for the LED pattern + * @color: The color LED to use for the LED pattern + * @rgb: The rgb value to set (if `color` indicates an RGB led) * @max_brightness_percentage: The max brightness (in percent) to use for the pattern * @freq: The pattern's frequency in mHz * * Start periodic feedback. */ gboolean -fbd_dev_leds_start_periodic (FbdDevLeds *self, FbdFeedbackLedColor color, - guint max_brightness_percentage, guint freq) +fbd_dev_leds_start_periodic (FbdDevLeds *self, + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb, + guint max_brightness_percentage, + guint freq) { FbdDevLed *led; @@ -197,7 +201,7 @@ fbd_dev_leds_start_periodic (FbdDevLeds *self, FbdFeedbackLedColor color, led = find_led_by_color (self, color); g_return_val_if_fail (led, FALSE); - fbd_dev_led_set_color (led, color); + fbd_dev_led_set_color (led, color, rgb); return fbd_dev_led_start_periodic (led, max_brightness_percentage, freq); } diff --git a/src/fbd-dev-leds.h b/src/fbd-dev-leds.h index 999dbd9..6387882 100644 --- a/src/fbd-dev-leds.h +++ b/src/fbd-dev-leds.h @@ -17,9 +17,11 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (FbdDevLeds, fbd_dev_leds, FBD, DEV_LEDS, GObject); FbdDevLeds *fbd_dev_leds_new (GError **error); -gboolean fbd_dev_leds_start_periodic (FbdDevLeds *self, - FbdFeedbackLedColor color, - guint max_brighness, guint freq); +gboolean fbd_dev_leds_start_periodic (FbdDevLeds *self, + FbdFeedbackLedColor color, + FbdLedRgbColor *rgb, + guint max_brighness, + guint freq); gboolean fbd_dev_leds_stop (FbdDevLeds *self, FbdFeedbackLedColor color); diff --git a/src/fbd-feedback-led.c b/src/fbd-feedback-led.c index 5013188..dc297b7 100644 --- a/src/fbd-feedback-led.c +++ b/src/fbd-feedback-led.c @@ -1,6 +1,8 @@ /* * Copyright (C) 2020 Purism SPC + * 2024 The Phosh Developers * SPDX-License-Identifier: GPL-3.0+ + * * Author: Guido Günther */ @@ -11,12 +13,12 @@ #include "fbd-feedback-led.h" #include "fbd-feedback-manager.h" +#include + /** - * SECTION:fbd-feedback-led - * @short_description: Describes a led feedback - * @Title: FbdFeedbackLed + * FbdFeedbackLed: * - * The #FbdFeedbackLed describes a feedback via an LED. It currently + * The `FbdFeedbackLed` describes a feedback via an LED. It currently * only supports periodic patterns. */ @@ -31,16 +33,124 @@ enum { static GParamSpec *props[PROP_LAST_PROP]; typedef struct _FbdFeedbackLed { - FbdFeedbackBase parent; + FbdFeedbackBase parent; - guint frequency; - guint priority; - guint max_brightness; - FbdFeedbackLedColor color; + guint frequency; + guint priority; + guint max_brightness; + char *color; } FbdFeedbackLed; G_DEFINE_TYPE (FbdFeedbackLed, fbd_feedback_led, FBD_TYPE_FEEDBACK_BASE) +/** + * ascii_to_int: + * @c: a character + * + * Interprets a character as digit. E.g. '1' will be converted to 1, + * 'C' or 'c' will be converted to 12. + * + * Returns: The integer value or -1 if the character isn't a hex digit. + */ +static int +hex_ascii_to_int (char c) +{ + switch (c) { + case '0'...'9': + return c - '0'; + break; + case 'a'...'f': + return 10 + c - 'a'; + break; + case 'A'...'F': + return 10 + c - 'A'; + break; + default: + return -1; + } +} + + +static gboolean +parse_hex_color (const char *color, FbdLedRgbColor *rgb) +{ + FbdLedRgbColor parsed = { 0 }; + + if (color[0] != '#') + return FALSE; + + if (strlen (color) != strlen ("#11AA00")) + return FALSE; + + if (!rgb) + return TRUE; + + for (int i = 1; color[i]; i++) { + int c = hex_ascii_to_int (color[i]); + + if (c < 0) + return FALSE; + + switch (i) { + case 1: + parsed.r |= hex_ascii_to_int (color[i]) << 4; + break; + case 2: + parsed.r |= hex_ascii_to_int (color[i]); + break; + case 3: + parsed.g |= hex_ascii_to_int (color[i]) << 4; + break; + case 4: + parsed.g |= hex_ascii_to_int (color[i]); + break; + case 5: + parsed.b |= hex_ascii_to_int (color[i]) << 4; + break; + case 6: + parsed.b |= hex_ascii_to_int (color[i]); + break; + } + } + + memcpy (rgb, &parsed, sizeof (FbdLedRgbColor)); + + return TRUE; +} + + +static FbdFeedbackLedColor +color_string_to_color (const char *color, FbdLedRgbColor *rgb) +{ + g_return_val_if_fail (!gm_str_is_null_or_empty (color), FBD_FEEDBACK_LED_COLOR_WHITE); + + if (g_strcmp0 (color, "red") == 0) { + if (rgb) + rgb->r = 255; + return FBD_FEEDBACK_LED_COLOR_RED; + } else if (g_strcmp0 (color, "green") == 0) { + if (rgb) + rgb->g = 255; + return FBD_FEEDBACK_LED_COLOR_GREEN; + } else if (g_strcmp0 (color, "blue") == 0) { + if (rgb) + rgb->b = 255; + return FBD_FEEDBACK_LED_COLOR_BLUE; + } else if (g_strcmp0 (color, "white") == 0) { + if (rgb) + rgb->r = rgb->g = rgb->b = 255; + return FBD_FEEDBACK_LED_COLOR_WHITE; + } else if (parse_hex_color (color, rgb)) { + return FBD_FEEDBACK_LED_COLOR_RGB; + } + + g_warning_once ("Can't parse color '%s' using white", color); + if (rgb) + rgb->r = rgb->g = rgb->b = 255; + return FBD_FEEDBACK_LED_COLOR_WHITE; +} + + static void fbd_feedback_led_set_property (GObject *object, guint property_id, @@ -60,7 +170,7 @@ fbd_feedback_led_set_property (GObject *object, self->max_brightness = g_value_get_uint (value); break; case PROP_COLOR: - self->color = g_value_get_enum (value); + self->color = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -68,6 +178,7 @@ fbd_feedback_led_set_property (GObject *object, } } + static void fbd_feedback_led_get_property (GObject *object, guint property_id, @@ -87,7 +198,7 @@ fbd_feedback_led_get_property (GObject *object, g_value_set_uint (value, self->max_brightness); break; case PROP_COLOR: - g_value_set_enum (value, self->color); + g_value_set_string (value, self->color); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -95,35 +206,44 @@ fbd_feedback_led_get_property (GObject *object, } } + static void fbd_feedback_led_run (FbdFeedbackBase *base) { FbdFeedbackLed *self = FBD_FEEDBACK_LED (base); FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); FbdDevLeds *dev = fbd_feedback_manager_get_dev_leds (manager); + FbdFeedbackLedColor color; + FbdLedRgbColor rgb; g_return_if_fail (FBD_IS_DEV_LEDS (dev)); - g_debug ("Periodic led feedback: self->max_brightness, self->frequency"); + g_debug ("Periodic led feedback: max brightness: %d, freq: %d", self->max_brightness, self->frequency); + color = color_string_to_color (self->color, &rgb); /* FIXME: handle priority */ fbd_dev_leds_start_periodic (dev, - self->color, + color, + &rgb, self->max_brightness, self->frequency); } + static void fbd_feedback_led_end (FbdFeedbackBase *base) { FbdFeedbackLed *self = FBD_FEEDBACK_LED (base); FbdFeedbackManager *manager = fbd_feedback_manager_get_default (); FbdDevLeds *dev = fbd_feedback_manager_get_dev_leds (manager); + FbdFeedbackLedColor color; + color = color_string_to_color (self->color, NULL); if (dev) - fbd_dev_leds_stop (dev, self->color); + fbd_dev_leds_stop (dev, color); fbd_feedback_base_done (FBD_FEEDBACK_BASE (self)); } + static gboolean fbd_feedback_led_is_available (FbdFeedbackBase *base) { @@ -133,6 +253,18 @@ fbd_feedback_led_is_available (FbdFeedbackBase *base) return FBD_IS_DEV_LEDS (dev); } + +static void +fbd_feedback_led_finalize (GObject *object) +{ + FbdFeedbackLed *self = FBD_FEEDBACK_LED (object); + + g_clear_pointer (&self->color, g_free); + + G_OBJECT_CLASS (fbd_feedback_led_parent_class)->finalize (object); +} + + static void fbd_feedback_led_class_init (FbdFeedbackLedClass *klass) { @@ -141,43 +273,42 @@ fbd_feedback_led_class_init (FbdFeedbackLedClass *klass) object_class->set_property = fbd_feedback_led_set_property; object_class->get_property = fbd_feedback_led_get_property; + object_class->finalize = fbd_feedback_led_finalize; base_class->run = fbd_feedback_led_run; base_class->end = fbd_feedback_led_end; base_class->is_available = fbd_feedback_led_is_available; + /** + * FbdFeedbackLed:frequency: + * + * The frequency the LED should blink with in mHz. + */ props[PROP_FREQUENCY] = - g_param_spec_uint ( - "frequency", - "Frequency", - "Led event frequency in mHz", - 0, G_MAXUINT, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - + g_param_spec_uint ("frequency", "", "", + 0, G_MAXUINT, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * FbdFeedbackLed:color: + * + * The color the LED should blink with. The color is given as color + * name or `rgb()` color value. + */ props[PROP_COLOR] = - g_param_spec_enum ( - "color", - "Color", - "The LED color", - FBD_TYPE_FEEDBACK_LED_COLOR, - FBD_FEEDBACK_LED_COLOR_WHITE, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - + g_param_spec_string ("color", "", "", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * FbdFeedbackLed:priority: * - * Priority of the led pattern. Led devices can only display a limited - * amount of patterns at time. In this case the pattern with the highest + * Priority of the LED pattern. LED devices can only display a limited + * amount of patterns at a time. In this case the pattern with the highest * priority wins. */ props[PROP_PRIORITY] = - g_param_spec_uint ( - "priority", - "Priority", - "The LED pattern priority", - 0, 255, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - + g_param_spec_uint ("priority", "", "", + 0, 255, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * FbdFeedbackLed:max-brightness: * @@ -185,16 +316,14 @@ fbd_feedback_led_class_init (FbdFeedbackLedClass *klass) * maximum brightness. */ props[PROP_MAX_BRIGHTNESS] = - g_param_spec_uint ( - "max-brightness", - "Maximum brightness percentage", - "Maximum brightness in the LED pattern", - 1, 100, 100, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_param_spec_uint ("max-brightness", "", "", + 1, 100, 100, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, PROP_LAST_PROP, props); } + static void fbd_feedback_led_init (FbdFeedbackLed *self) { diff --git a/src/fbd-feedback-led.h b/src/fbd-feedback-led.h index 783970f..f67af6c 100644 --- a/src/fbd-feedback-led.h +++ b/src/fbd-feedback-led.h @@ -9,6 +9,16 @@ G_BEGIN_DECLS +/** + * FbdDevLedColor: + * @FBD_FEEDBACK_LED_COLOR_WHITE: A white LED + * @FBD_FEEDBACK_LED_COLOR_RED: A red LED + * @FBD_FEEDBACK_LED_COLOR_GREEN: A green LED + * @FBD_FEEDBACK_LED_COLOR_BLUE: A blue LED + * @FBD_FEEDBACK_LED_COLOR_RGB: A multicolor LED that can display arbitrary RGB values + * + * The color of a hardware LED. + */ typedef enum _FbdFeedbackLedColor { FBD_FEEDBACK_LED_COLOR_WHITE = 0, FBD_FEEDBACK_LED_COLOR_RED = 1, @@ -18,6 +28,10 @@ typedef enum _FbdFeedbackLedColor { FBD_FEEDBACK_LED_COLOR_LAST = FBD_FEEDBACK_LED_COLOR_RGB, } FbdFeedbackLedColor; +typedef struct { + guint r, g, b; +} FbdLedRgbColor; + #define FBD_TYPE_FEEDBACK_LED (fbd_feedback_led_get_type ()) G_DECLARE_FINAL_TYPE (FbdFeedbackLed, fbd_feedback_led, FBD, FEEDBACK_LED, FbdFeedbackBase); diff --git a/src/fbd-feedback-manager.c b/src/fbd-feedback-manager.c index 0fa7f23..4560a95 100644 --- a/src/fbd-feedback-manager.c +++ b/src/fbd-feedback-manager.c @@ -16,7 +16,6 @@ #include "fbd-feedback-theme.h" #include "fbd-theme-expander.h" -#define GMOBILE_USE_UNSTABLE_API #include #include diff --git a/src/meson.build b/src/meson.build index 2ae7691..f538ef1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -57,11 +57,12 @@ fbd_lib = static_library( sources, include_directories : fbd_inc, dependencies : fbd_deps, + c_args: '-DGMOBILE_USE_UNSTABLE_API', install : false, ) fbd_dep = declare_dependency( - sources: generated_dbus_sources, + sources: [generated_dbus_sources, fbd_enum_sources], include_directories : fbd_inc, link_with : fbd_lib, dependencies : fbd_deps, diff --git a/tests/meson.build b/tests/meson.build index a8672a3..509a663 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -78,6 +78,7 @@ test_fbd_deps = [ # HW independent tests fbd_tests = [ + 'fbd-feedback-led', 'fbd-feedback-profile', 'fbd-feedback-theme', 'fbd-event', diff --git a/tests/test-fbd-feedback-led.c b/tests/test-fbd-feedback-led.c new file mode 100644 index 0000000..2b7bb0e --- /dev/null +++ b/tests/test-fbd-feedback-led.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2024 The Phosh Developers + * + * SPDX-License-Identifier: GPL-3.0+ + * + * Author: Guido Günther + */ + +#define GMOBILE_USE_UNSTABLE_API +#include "fbd-feedback-led.c" + + +static void +test_fbd_feedback_led_parse_color (void) +{ + FbdLedRgbColor rgb = { 0 }; + + g_assert_true (parse_hex_color ("#11aaBB", &rgb)); + g_assert_cmpint (rgb.r, ==, 0x11); + g_assert_cmpint (rgb.g, ==, 0xaa); + g_assert_cmpint (rgb.b, ==, 0xbb); + + g_assert_true (parse_hex_color ("#000000", &rgb)); + g_assert_cmpint (rgb.r, ==, 0x00); + g_assert_cmpint (rgb.g, ==, 0x00); + g_assert_cmpint (rgb.b, ==, 0x00); + + g_assert_false (parse_hex_color ("#1bc", &rgb)); + g_assert_false (parse_hex_color ("11aaBB", &rgb)); + g_assert_false (parse_hex_color ("", &rgb)); + g_assert_false (parse_hex_color ("#", &rgb)); + g_assert_false (parse_hex_color ("#QWERTY", &rgb)); +} + + +static void +test_fbd_feedback_led_color_string_to_color (void) +{ + FbdLedRgbColor rgb = { 0 }; + + g_assert_cmpint (color_string_to_color ("red", NULL), ==, FBD_FEEDBACK_LED_COLOR_RED); + + g_assert_cmpint (color_string_to_color ("#11aaBB", &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); + g_assert_cmpint (rgb.r, ==, 0x11); + g_assert_cmpint (rgb.g, ==, 0xaa); + g_assert_cmpint (rgb.b, ==, 0xbb); + + g_assert_cmpint (color_string_to_color ("#00FF00", &rgb), ==, FBD_FEEDBACK_LED_COLOR_RGB); + g_assert_cmpint (rgb.r, ==, 0x00); + g_assert_cmpint (rgb.g, ==, 0xFF); + g_assert_cmpint (rgb.b, ==, 0x00); +} + + +gint +main (gint argc, gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func("/feedbackd/fbd/feedback-led/parse-color", test_fbd_feedback_led_parse_color); + g_test_add_func("/feedbackd/fbd/feedback-led/color-string-to-color", + test_fbd_feedback_led_color_string_to_color); + + return g_test_run(); +}