Files

435 lines
13 KiB
C

#include "optifetch.h"
#define MAX_ALIGN_IDS 32
typedef struct
{
char id[32];
int max_width;
} AlignID;
static AlignID align_ids[MAX_ALIGN_IDS];
static int align_count = 0;
static int current_col = 0;
static int skip_output = 0;
static int current_line_num = 0;
static int current_pass = 1;
static int logo_line_idx = 0;
static int prev_line_had_logo = 0;
static int in_ansi_escape = 0;
// NOUVEAU : Génère le code ANSI pour un pourcentage dynamique
static void get_dynamic_color(double pct, char *out, size_t size)
{
if (pct >= 80.0)
{
snprintf(out, size, "\033[38;2;255;50;50m"); // Rouge
}
else if (pct >= 50.0)
{
snprintf(out, size, "\033[38;2;255;165;0m"); // Orange
}
else
{
snprintf(out, size, "\033[38;2;0;200;0m"); // Vert
}
}
static int get_align_width(const char *id)
{
for (int i = 0; i < align_count; i++)
{
if (strcmp(align_ids[i].id, id) == 0)
return align_ids[i].max_width;
}
return 0;
}
static void set_align_width(const char *id, int width)
{
for (int i = 0; i < align_count; i++)
{
if (strcmp(align_ids[i].id, id) == 0)
{
if (width > align_ids[i].max_width)
align_ids[i].max_width = width;
return;
}
}
if (align_count < MAX_ALIGN_IDS)
{
snprintf(align_ids[align_count].id, sizeof(align_ids[align_count].id), "%.31s", id);
align_ids[align_count].max_width = width;
align_count++;
}
}
static void my_putchar(char c)
{
if (skip_output)
return;
if (current_pass == 2)
{
putchar(c);
}
if (c == '\033')
{
in_ansi_escape = 1;
return;
}
if (in_ansi_escape)
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
in_ansi_escape = 0;
}
return;
}
if ((c & 0xC0) != 0x80)
{
current_col++;
}
}
static void my_putstr(const char *s)
{
for (int i = 0; s[i]; i++)
my_putchar(s[i]);
}
static void print_color(const char *params, int is_bg)
{
if (skip_output || current_pass == 1)
return;
int r, g, b;
if (sscanf(params, "%d,%d,%d", &r, &g, &b) == 3)
{
printf("\033[%d;2;%d;%d;%dm", is_bg ? 48 : 38, r, g, b);
return;
}
if (strcmp(params, "red") == 0)
r = 255, g = 0, b = 0;
else if (strcmp(params, "green") == 0)
r = 0, g = 255, b = 0;
else if (strcmp(params, "blue") == 0)
r = 0, g = 0, b = 255;
else if (strcmp(params, "yellow") == 0)
r = 255, g = 255, b = 0;
else if (strcmp(params, "cyan") == 0)
r = 0, g = 255, b = 255;
else if (strcmp(params, "magenta") == 0)
r = 255, g = 0, b = 255;
else if (strcmp(params, "white") == 0)
r = 255, g = 255, b = 255;
else if (strcmp(params, "black") == 0)
r = 0, g = 0, b = 0;
else
r = 200, g = 200, b = 200;
printf("\033[%d;2;%d;%d;%dm", is_bg ? 48 : 38, r, g, b);
}
static void print_variable(const char *name, SysInfo *info)
{
if (skip_output)
return;
char buf[1024];
buf[0] = '\0';
if (strcmp(name, "logo") == 0 || strcmp(name, "small_logo") == 0)
{
get_logo_line(info->os_id, name[0] == 's', logo_line_idx, buf, sizeof(buf));
}
else if (strcmp(name, "distro_color") == 0)
{
if (strlen(info->distro_color) > 0)
{
snprintf(buf, sizeof(buf), "\033[%sm", info->distro_color);
}
else
{
snprintf(buf, sizeof(buf), "\033[0m");
}
}
else if (strcmp(name, "user") == 0)
snprintf(buf, sizeof(buf), "%s", info->user);
else if (strcmp(name, "host") == 0)
snprintf(buf, sizeof(buf), "%s", info->hostname);
else if (strcmp(name, "os") == 0)
snprintf(buf, sizeof(buf), "%s", info->os);
else if (strcmp(name, "kernel") == 0)
snprintf(buf, sizeof(buf), "%s", info->kernel);
else if (strcmp(name, "uptime") == 0)
snprintf(buf, sizeof(buf), "%s", info->uptime);
else if (strcmp(name, "arch") == 0)
snprintf(buf, sizeof(buf), "%s", info->arch);
else if (strcmp(name, "shell") == 0)
snprintf(buf, sizeof(buf), "%s", info->shell);
else if (strcmp(name, "cpu") == 0)
snprintf(buf, sizeof(buf), "%s", info->cpu);
else if (strcmp(name, "cores") == 0)
snprintf(buf, sizeof(buf), "%ld", info->cores);
else if (strcmp(name, "cpu_max_freq") == 0)
snprintf(buf, sizeof(buf), "%ld", info->cpu_max_freq);
else if (strcmp(name, "gpu") == 0)
snprintf(buf, sizeof(buf), "%s", info->gpu);
else if (strcmp(name, "de") == 0)
snprintf(buf, sizeof(buf), "%s", info->de);
else if (strcmp(name, "wm") == 0)
snprintf(buf, sizeof(buf), "%s", info->wm);
else if (strcmp(name, "term") == 0)
snprintf(buf, sizeof(buf), "%s", info->term);
else if (strcmp(name, "packages") == 0)
snprintf(buf, sizeof(buf), "%s", info->packages);
else if (strcmp(name, "battery") == 0)
snprintf(buf, sizeof(buf), "%s", info->battery);
else if (strcmp(name, "bat_status") == 0)
snprintf(buf, sizeof(buf), "%s", info->battery_status);
else if (strcmp(name, "date") == 0)
snprintf(buf, sizeof(buf), "%s", info->date);
else if (strcmp(name, "time") == 0)
snprintf(buf, sizeof(buf), "%s", info->time_str);
else if (strcmp(name, "ip_local") == 0)
snprintf(buf, sizeof(buf), "%s", info->ip_local);
else if (strcmp(name, "ip_public") == 0)
snprintf(buf, sizeof(buf), "%s", info->ip_public);
else if (strcmp(name, "dns") == 0)
snprintf(buf, sizeof(buf), "%s", info->dns);
else if (strcmp(name, "wifi") == 0)
snprintf(buf, sizeof(buf), "%s", info->wifi[0] ? info->wifi : "N/A");
else if (strcmp(name, "host_model") == 0)
snprintf(buf, sizeof(buf), "%s", info->host_model);
else if (strcmp(name, "display_server") == 0)
snprintf(buf, sizeof(buf), "%s", info->display_server);
else if (strcmp(name, "theme") == 0)
snprintf(buf, sizeof(buf), "%s", info->theme);
else if (strcmp(name, "font") == 0)
snprintf(buf, sizeof(buf), "%s", info->font);
else if (strcmp(name, "locale") == 0)
snprintf(buf, sizeof(buf), "%s", info->locale);
else if (strcmp(name, "disk_fs") == 0)
snprintf(buf, sizeof(buf), "%s", info->disk_fs);
// NOUVEAU : Gestion des variables avec unités et couleurs dynamiques
else if (strncmp(name, "ram", 3) == 0)
{
char unit[128] = "mb";
if (strlen(name) > 4 && name[3] == ':')
snprintf(unit, sizeof(unit), "%s", name + 4);
if (strcmp(unit, "%") == 0)
{
double pct = info->ram_total_mb ? (double)info->ram_used_mb / (double)info->ram_total_mb * 100.0 : 0;
char col[32];
get_dynamic_color(pct, col, sizeof(col));
snprintf(buf, sizeof(buf), "%s%.1f%%\033[0m", col, pct);
}
else
{
if (strcmp(unit, "gb") == 0)
snprintf(buf, sizeof(buf), "%.1fGB / %.1fGB", (double)info->ram_used_mb / 1024.0, (double)info->ram_total_mb / 1024.0);
else
snprintf(buf, sizeof(buf), "%luMB / %luMB", info->ram_used_mb, info->ram_total_mb);
}
}
else if (strncmp(name, "swap", 4) == 0)
{
char unit[128] = "mb";
if (strlen(name) > 5 && name[4] == ':')
snprintf(unit, sizeof(unit), "%s", name + 5);
if (strcmp(unit, "%") == 0)
{
double pct = info->swap_total_mb ? (double)info->swap_used_mb / (double)info->swap_total_mb * 100.0 : 0;
char col[32];
get_dynamic_color(pct, col, sizeof(col));
snprintf(buf, sizeof(buf), "%s%.1f%%\033[0m", col, pct);
}
else
{
if (strcmp(unit, "gb") == 0)
snprintf(buf, sizeof(buf), "%.1fGB / %.1fGB", (double)info->swap_used_mb / 1024.0, (double)info->swap_total_mb / 1024.0);
else
snprintf(buf, sizeof(buf), "%luMB / %luMB", info->swap_used_mb, info->swap_total_mb);
}
}
else if (strncmp(name, "disk", 4) == 0)
{
char unit[128] = "mb";
if (strlen(name) > 5 && name[4] == ':')
snprintf(unit, sizeof(unit), "%s", name + 5);
if (strcmp(unit, "%") == 0)
{
double pct = info->disk_total_mb ? (double)info->disk_used_mb / (double)info->disk_total_mb * 100.0 : 0;
char col[32];
get_dynamic_color(pct, col, sizeof(col));
snprintf(buf, sizeof(buf), "%s%.1f%%\033[0m", col, pct);
}
else
{
if (strcmp(unit, "gb") == 0)
snprintf(buf, sizeof(buf), "%.1fGB / %.1fGB", (double)info->disk_used_mb / 1024.0, (double)info->disk_total_mb / 1024.0);
else
snprintf(buf, sizeof(buf), "%luMB / %luMB", info->disk_used_mb, info->disk_total_mb);
}
}
else
{
snprintf(buf, sizeof(buf), "{%s}", name);
}
my_putstr(buf);
}
static void process_line(const char *line, SysInfo *info)
{
int i = 0;
current_col = 0;
skip_output = 0;
in_ansi_escape = 0;
int has_logo = (strstr(line, "{logo}") != NULL || strstr(line, "{small_logo}") != NULL);
if (has_logo && !prev_line_had_logo)
{
logo_line_idx = 0;
}
while (line[i] != '\0' && line[i] != '\n')
{
if (line[i] == '{')
{
int j = i + 1;
char token[128];
int k = 0;
while (line[j] != '}' && line[j] != '\0' && line[j] != '\n' && k < 127)
{
token[k++] = line[j++];
}
token[k] = '\0';
if (line[j] == '}')
{
i = j + 1;
if (strcmp(token, "if:laptop") == 0)
skip_output = (strcmp(info->battery, "N/A") == 0);
else if (strcmp(token, "if:gpu") == 0)
skip_output = (strlen(info->gpu) == 0);
else if (strcmp(token, "if:swap") == 0)
skip_output = (info->swap_total_mb == 0);
else if (strcmp(token, "if:wifi") == 0)
skip_output = (strlen(info->wifi) == 0);
else if (strcmp(token, "endif") == 0)
skip_output = 0;
else if (strncmp(token, "align:", 6) == 0)
{
if (!skip_output)
{
if (current_pass == 1)
{
set_align_width(token + 6, current_col);
}
int target = get_align_width(token + 6);
while (current_col < target)
my_putchar(' ');
}
}
else if (strncmp(token, "fg:", 3) == 0)
print_color(token + 3, 0);
else if (strncmp(token, "bg:", 3) == 0)
print_color(token + 3, 1);
else if (strcmp(token, "reset") == 0)
{
if (!skip_output && current_pass == 2)
printf("\033[0m");
}
else if (strcmp(token, "bold") == 0)
{
if (!skip_output && current_pass == 2)
printf("\033[1m");
}
else
print_variable(token, info);
}
else
{
my_putchar(line[i++]);
}
}
else
{
my_putchar(line[i++]);
}
}
if (current_pass == 2 && !skip_output)
putchar('\n');
current_line_num++;
prev_line_had_logo = has_logo;
if (has_logo)
logo_line_idx++;
}
void render_config(const char *path, SysInfo *info)
{
FILE *f = fopen(path, "r");
if (!f)
return;
static char lines[200][1024];
int line_count = 0;
while (fgets(lines[line_count], sizeof(lines[line_count]), f) && line_count < 200)
{
line_count++;
}
fclose(f);
int logo_h = 0;
char logo_token[20] = "";
for (int i = 0; i < line_count; i++)
{
if (strstr(lines[i], "{logo}"))
{
snprintf(logo_token, sizeof(logo_token), "{logo}");
logo_h = get_logo_height(info->os_id, 0);
}
if (strstr(lines[i], "{small_logo}"))
{
snprintf(logo_token, sizeof(logo_token), "{small_logo}");
int sh = get_logo_height(info->os_id, 1);
if (sh > logo_h)
logo_h = sh;
}
}
if (strlen(logo_token) > 0)
{
while (line_count < logo_h && line_count < 200)
{
snprintf(lines[line_count++], 1024, "%s{align:L} \n", logo_token);
}
}
align_count = 0;
current_pass = 1;
current_line_num = 0;
logo_line_idx = 0;
prev_line_had_logo = 0;
for (int i = 0; i < line_count; i++)
{
process_line(lines[i], info);
}
current_pass = 2;
current_line_num = 0;
logo_line_idx = 0;
prev_line_had_logo = 0;
for (int i = 0; i < line_count; i++)
{
process_line(lines[i], info);
}
}