diff --git a/src/fbd-dev-leds.c b/src/fbd-dev-leds.c index 1b2f837..bd498e2 100644 --- a/src/fbd-dev-leds.c +++ b/src/fbd-dev-leds.c @@ -25,14 +25,22 @@ * It currently only supports one pattern per led at a time. */ -#define LED_BRIGHTNESS_ATTR "brightness" -#define LED_MAX_BRIGHTNESS_ATTR "max_brightness" -#define LED_PATTERN_ATTR "pattern" -#define LED_SUBSYSTEM "leds" +#define LED_BRIGHTNESS_ATTR "brightness" +#define LED_MAX_BRIGHTNESS_ATTR "max_brightness" +#define LED_MULTI_INDEX_ATTR "multi_index" +#define LED_MULTI_INTENSITY_ATTR "multi_intensity" +#define LED_MULTI_INDEX_RED "red" +#define LED_MULTI_INDEX_GREEN "green" +#define LED_MULTI_INDEX_BLUE "blue" +#define LED_PATTERN_ATTR "pattern" +#define LED_SUBSYSTEM "leds" typedef struct _FbdDevLed { GUdevDevice *dev; guint max_brightness; + guint red_index; + guint green_index; + guint blue_index; /* * We just use the colors from the feedback until we * do rgb mixing, etc @@ -80,7 +88,7 @@ find_led_by_color (FbdDevLeds *self, FbdFeedbackLedColor color) for (GSList *l = self->leds; l != NULL; l = l->next) { FbdDevLed *led = l->data; - if (led->color == color) + if (led->color == FBD_FEEDBACK_LED_COLOR_RGB || led->color == color) return led; } @@ -119,6 +127,8 @@ initable_init (GInitable *initable, for (int i = 0; i <= FBD_FEEDBACK_LED_COLOR_LAST; i++) { g_autofree char *color = NULL; g_autofree char *enum_name = NULL; + const gchar * const *index; + guint counter = 0; gchar *c; enum_name = g_enum_to_string (FBD_TYPE_FEEDBACK_LED_COLOR, i); @@ -127,6 +137,7 @@ initable_init (GInitable *initable, if (g_strstr_len (name, -1, color)) { g_autoptr (GError) err = NULL; guint brightness = g_udev_device_get_sysfs_attr_as_int (dev, LED_MAX_BRIGHTNESS_ATTR); + index = g_udev_device_get_sysfs_attr_as_strv (dev, LED_MULTI_INDEX_ATTR); if (!brightness) continue; @@ -135,6 +146,25 @@ initable_init (GInitable *initable, led->dev = g_object_ref (dev); led->color = i; led->max_brightness = brightness; + + if (index) { + for (int j = 0; j < g_strv_length ((gchar **) index); j++) { + g_debug ("Index: %s", index[j]); + if (g_strcmp0 (index[j], LED_MULTI_INDEX_RED) == 0) { + led->red_index = counter; + counter++; + } else if (g_strcmp0 (index[j], LED_MULTI_INDEX_GREEN) == 0) { + led->green_index = counter; + counter++; + } else if (g_strcmp0 (index[j], LED_MULTI_INDEX_BLUE) == 0) { + led->blue_index = counter; + counter++; + } else { + g_warning ("Unsupport LED color index: %d %s", counter, index[j]); + } + } + } + path = g_udev_device_get_sysfs_path (dev); g_debug ("LED at '%s' usable", path); self->leds = g_slist_append (self->leds, led); @@ -221,6 +251,43 @@ fbd_dev_leds_start_periodic (FbdDevLeds *self, FbdFeedbackLedColor color, led = find_led_by_color (self, color); g_return_val_if_fail (led, FALSE); + if (led->color == FBD_FEEDBACK_LED_COLOR_RGB) { + g_autofree char *intensity = NULL; + guint colors[] = { 0, 0, 0 }; + switch (color) { + case FBD_FEEDBACK_LED_COLOR_WHITE: + colors[led->red_index] = led->max_brightness; + colors[led->green_index] = led->max_brightness; + colors[led->blue_index] = led->max_brightness; + break; + case FBD_FEEDBACK_LED_COLOR_RED: + colors[led->red_index] = led->max_brightness; + colors[led->green_index] = 0; + colors[led->blue_index] = 0; + break; + case FBD_FEEDBACK_LED_COLOR_GREEN: + colors[led->red_index] = 0; + colors[led->green_index] = led->max_brightness; + colors[led->blue_index] = 0; + break; + case FBD_FEEDBACK_LED_COLOR_BLUE: + colors[led->red_index] = 0; + colors[led->green_index] = 0; + colors[led->blue_index] = led->max_brightness; + 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]); + fbd_dev_led_set_brightness (led, led->max_brightness); + success = fbd_udev_set_sysfs_path_attr_as_string (led->dev, LED_MULTI_INTENSITY_ATTR, intensity, &err); + if (!success) { + g_warning ("Failed to set multi intensity: %s", err->message); + g_clear_error (&err); + } + } + max = led->max_brightness * (max_brightness_percentage / 100.0); /* ms mHz T/2 */ t = 1000.0 * 1000.0 / freq / 2.0; diff --git a/src/fbd-feedback-led.h b/src/fbd-feedback-led.h index 85e076d..783970f 100644 --- a/src/fbd-feedback-led.h +++ b/src/fbd-feedback-led.h @@ -14,7 +14,8 @@ typedef enum _FbdFeedbackLedColor { FBD_FEEDBACK_LED_COLOR_RED = 1, FBD_FEEDBACK_LED_COLOR_GREEN = 2, FBD_FEEDBACK_LED_COLOR_BLUE = 3, - FBD_FEEDBACK_LED_COLOR_LAST = FBD_FEEDBACK_LED_COLOR_BLUE, + FBD_FEEDBACK_LED_COLOR_RGB = 4, + FBD_FEEDBACK_LED_COLOR_LAST = FBD_FEEDBACK_LED_COLOR_RGB, } FbdFeedbackLedColor; #define FBD_TYPE_FEEDBACK_LED (fbd_feedback_led_get_type ()) diff --git a/src/fbd-ledctrl.c b/src/fbd-ledctrl.c index 873a58a..fd6612b 100644 --- a/src/fbd-ledctrl.c +++ b/src/fbd-ledctrl.c @@ -17,6 +17,7 @@ #include #define LED_BRIGHTNESS_ATTR "brightness" +#define LED_MULTI_INTENSITY_ATTR "multi_intensity" #define LED_PATTERN_ATTR "pattern" #define LED_REPEAT_ATTR "repeat" #define LED_TRIGGER_ATTR "trigger" @@ -126,6 +127,9 @@ set_perms (const char *sysfs_path, const char *trigger, const char *gname) if (!set_sysfs_attr_perm (sysfs_path, LED_BRIGHTNESS_ATTR, group->gr_gid)) return FALSE; + // Attribute is optional + set_sysfs_attr_perm (sysfs_path, LED_MULTI_INTENSITY_ATTR, group->gr_gid); + if (!g_strcmp0 (trigger, LED_TRIGGER_PATTERN)) { if (!set_sysfs_attr_perm (sysfs_path, LED_PATTERN_ATTR, group->gr_gid)) success = FALSE;