#include #include #include #include #include #include /* Convert sRGB to Linear RGB */ double srgb_to_linear(double value) { if (value <= 0.04045) { return value / 12.92; } else { return pow((value + 0.055) / 1.055, 2.4); } } /* Convert Linear RGB to sRGB */ double linear_to_srgb(double value) { if (value <= 0.0031308) { return value * 12.92; } else { return 1.055 * pow(value, 1.0 / 2.4) - 0.055; } } /* Interpolate between two colors in Linear RGB space */ void interpolate_color_linear(const char *color1, const char *color2, double t, char *output) { unsigned int r1, g1, b1, r2, g2, b2; sscanf(color1, "#%02x%02x%02x", &r1, &g1, &b1); sscanf(color2, "#%02x%02x%02x", &r2, &g2, &b2); // Convert sRGB to linear RGB double lr1 = srgb_to_linear(r1 / 255.0); double lg1 = srgb_to_linear(g1 / 255.0); double lb1 = srgb_to_linear(b1 / 255.0); double lr2 = srgb_to_linear(r2 / 255.0); double lg2 = srgb_to_linear(g2 / 255.0); double lb2 = srgb_to_linear(b2 / 255.0); // Interpolate in linear RGB space double lr = lr1 + t * (lr2 - lr1); double lg = lg1 + t * (lg2 - lg1); double lb = lb1 + t * (lb2 - lb1); // Convert back to sRGB unsigned int r = (unsigned int)(linear_to_srgb(lr) * 255.0); unsigned int g = (unsigned int)(linear_to_srgb(lg) * 255.0); unsigned int b = (unsigned int)(linear_to_srgb(lb) * 255.0); // Format as hex output snprintf(output, 8, "#%02x%02x%02x", r, g, b); } int main() { /* Define the colors to cycle through */ const char *breathing_colors[] = { "#ffe667", // Yellow "#f27049", // Orange "#3dd762", // Green }; int color_count = sizeof(breathing_colors) / sizeof(breathing_colors[0]); int current_index = 0; double t = 0.0; // Interpolation factor char current_color[8]; struct timespec ts = { 0, 5000000 }; // 5ms sleep while (1) { /* Interpolate the current color */ interpolate_color_linear( breathing_colors[current_index], breathing_colors[(current_index + 1) % color_count], t, current_color ); /* Write the current color to a file */ FILE *f = fopen("/tmp/breathing_color", "w"); if (f) { fprintf(f, "%s\n", current_color); fclose(f); } /* Increment interpolation factor */ t += 0.005; // Adjust the speed of transition (smaller value = slower transition) if (t >= 1.0) { t = 0.0; // Reset interpolation current_index = (current_index + 1) % color_count; // Move to the next color } /* Sleep for 5ms */ nanosleep(&ts, NULL); } return 0; }