config: handle transform opts; make implementation futureproof
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ic67d4485d08114f605a6dc2535224b276a6a6964
This commit is contained in:
parent
1a366d2445
commit
5fd2e5660f
1 changed files with 186 additions and 9 deletions
195
src/config.c
195
src/config.c
|
|
@ -52,11 +52,81 @@ static bool parse_bool(const char *value) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Parse integer value from string
|
||||
// Parse scaling mode from string
|
||||
static chroma_scale_mode_t parse_scale_mode(const char *value) {
|
||||
if (!value)
|
||||
return CHROMA_SCALE_FILL; // default
|
||||
|
||||
if (strcasecmp(value, "fill") == 0) {
|
||||
return CHROMA_SCALE_FILL;
|
||||
} else if (strcasecmp(value, "fit") == 0) {
|
||||
return CHROMA_SCALE_FIT;
|
||||
} else if (strcasecmp(value, "stretch") == 0) {
|
||||
return CHROMA_SCALE_STRETCH;
|
||||
} else if (strcasecmp(value, "center") == 0) {
|
||||
return CHROMA_SCALE_CENTER;
|
||||
}
|
||||
|
||||
chroma_log("WARN", "Unknown scaling mode: %s (using fill)", value);
|
||||
return CHROMA_SCALE_FILL;
|
||||
}
|
||||
|
||||
// Parse filter quality from string
|
||||
static chroma_filter_quality_t parse_filter_quality(const char *value) {
|
||||
if (!value)
|
||||
return CHROMA_FILTER_LINEAR; // default
|
||||
|
||||
if (strcasecmp(value, "nearest") == 0) {
|
||||
return CHROMA_FILTER_NEAREST;
|
||||
} else if (strcasecmp(value, "linear") == 0) {
|
||||
return CHROMA_FILTER_LINEAR;
|
||||
} else if (strcasecmp(value, "bilinear") == 0) {
|
||||
return CHROMA_FILTER_BILINEAR;
|
||||
} else if (strcasecmp(value, "trilinear") == 0) {
|
||||
return CHROMA_FILTER_TRILINEAR;
|
||||
}
|
||||
|
||||
chroma_log("WARN", "Unknown filter quality: %s (using linear)", value);
|
||||
return CHROMA_FILTER_LINEAR;
|
||||
}
|
||||
|
||||
// Get string representation of scaling mode
|
||||
static const char *scale_mode_to_string(chroma_scale_mode_t mode) {
|
||||
switch (mode) {
|
||||
case CHROMA_SCALE_FILL:
|
||||
return "fill";
|
||||
case CHROMA_SCALE_FIT:
|
||||
return "fit";
|
||||
case CHROMA_SCALE_STRETCH:
|
||||
return "stretch";
|
||||
case CHROMA_SCALE_CENTER:
|
||||
return "center";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// Get string representation of filter quality
|
||||
static const char *filter_quality_to_string(chroma_filter_quality_t quality) {
|
||||
switch (quality) {
|
||||
case CHROMA_FILTER_NEAREST:
|
||||
return "nearest";
|
||||
case CHROMA_FILTER_LINEAR:
|
||||
return "linear";
|
||||
case CHROMA_FILTER_BILINEAR:
|
||||
return "bilinear";
|
||||
case CHROMA_FILTER_TRILINEAR:
|
||||
return "trilinear";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// Output-to-image mapping
|
||||
static int add_output_mapping(chroma_config_t *config, const char *output_name,
|
||||
const char *image_path) {
|
||||
const char *image_path,
|
||||
chroma_scale_mode_t scale_mode,
|
||||
chroma_filter_quality_t filter_quality) {
|
||||
if (!config || !output_name || !image_path) {
|
||||
return CHROMA_ERROR_INIT;
|
||||
}
|
||||
|
|
@ -87,10 +157,14 @@ static int add_output_mapping(chroma_config_t *config, const char *output_name,
|
|||
|
||||
strcpy(mapping->output_name, output_name);
|
||||
strcpy(mapping->image_path, image_path);
|
||||
mapping->scale_mode = scale_mode;
|
||||
mapping->filter_quality = filter_quality;
|
||||
|
||||
config->mapping_count++;
|
||||
|
||||
chroma_log("DEBUG", "Added mapping: %s -> %s", output_name, image_path);
|
||||
chroma_log("DEBUG", "Added mapping: %s -> %s (scale: %s, filter: %s)",
|
||||
output_name, image_path, scale_mode_to_string(scale_mode),
|
||||
filter_quality_to_string(filter_quality));
|
||||
chroma_log("TRACE", "Output mapping %d: '%s' -> '%s' (path length: %zu)",
|
||||
config->mapping_count, output_name, image_path, path_len);
|
||||
return CHROMA_OK;
|
||||
|
|
@ -106,6 +180,10 @@ static void init_default_config(chroma_config_t *config) {
|
|||
config->daemon_mode = false;
|
||||
config->mapping_count = 0;
|
||||
|
||||
// Set default scaling and filtering
|
||||
config->default_scale_mode = CHROMA_SCALE_FILL;
|
||||
config->default_filter_quality = CHROMA_FILTER_LINEAR;
|
||||
|
||||
// Set default image path (can be overridden)
|
||||
const char *home = getenv("HOME");
|
||||
if (home) {
|
||||
|
|
@ -181,6 +259,23 @@ static int parse_config_line(chroma_config_t *config, char *line,
|
|||
chroma_log("TRACE",
|
||||
"Daemon mode configuration: key='%s', value='%s', parsed=%s",
|
||||
key, value, config->daemon_mode ? "true" : "false");
|
||||
} else if (strcasecmp(key, "scale_mode") == 0 ||
|
||||
strcasecmp(key, "default_scale_mode") == 0) {
|
||||
config->default_scale_mode = parse_scale_mode(value);
|
||||
chroma_log("DEBUG", "Set default scale mode: %s",
|
||||
scale_mode_to_string(config->default_scale_mode));
|
||||
chroma_log("TRACE",
|
||||
"Scale mode configuration: key='%s', value='%s', parsed=%s", key,
|
||||
value, scale_mode_to_string(config->default_scale_mode));
|
||||
} else if (strcasecmp(key, "filter_quality") == 0 ||
|
||||
strcasecmp(key, "default_filter_quality") == 0) {
|
||||
config->default_filter_quality = parse_filter_quality(value);
|
||||
chroma_log("DEBUG", "Set default filter quality: %s",
|
||||
filter_quality_to_string(config->default_filter_quality));
|
||||
chroma_log("TRACE",
|
||||
"Filter quality configuration: key='%s', value='%s', parsed=%s",
|
||||
key, value,
|
||||
filter_quality_to_string(config->default_filter_quality));
|
||||
} else if (strncasecmp(key, "output.", 7) == 0) {
|
||||
// Output-specific mapping: e.g., output.DP-1=/path/to/image.jpg
|
||||
const char *output_name = key + 7;
|
||||
|
|
@ -190,6 +285,46 @@ static int parse_config_line(chroma_config_t *config, char *line,
|
|||
return CHROMA_OK;
|
||||
}
|
||||
|
||||
// Check for extended output configuration with properties
|
||||
// Format: output.DP-1.scale = fill
|
||||
// Format: output.DP-1.filter = linear
|
||||
char *dot = strchr(output_name, '.');
|
||||
if (dot) {
|
||||
// This is an output property (scale or filter)
|
||||
*dot = '\0';
|
||||
const char *property = dot + 1;
|
||||
|
||||
// Find existing mapping for this output
|
||||
chroma_config_mapping_t *mapping = NULL;
|
||||
for (int i = 0; i < config->mapping_count; i++) {
|
||||
if (strcmp(config->mappings[i].output_name, output_name) == 0) {
|
||||
mapping = &config->mappings[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapping) {
|
||||
chroma_log("WARN", "Output %s not found for property %s (line %d)",
|
||||
output_name, property, line_number);
|
||||
return CHROMA_OK;
|
||||
}
|
||||
|
||||
if (strcasecmp(property, "scale") == 0) {
|
||||
mapping->scale_mode = parse_scale_mode(value);
|
||||
chroma_log("DEBUG", "Set scale mode for output %s: %s", output_name,
|
||||
scale_mode_to_string(mapping->scale_mode));
|
||||
} else if (strcasecmp(property, "filter") == 0) {
|
||||
mapping->filter_quality = parse_filter_quality(value);
|
||||
chroma_log("DEBUG", "Set filter quality for output %s: %s", output_name,
|
||||
filter_quality_to_string(mapping->filter_quality));
|
||||
} else {
|
||||
chroma_log("WARN", "Unknown output property: %s (line %d)", property,
|
||||
line_number);
|
||||
}
|
||||
|
||||
return CHROMA_OK;
|
||||
}
|
||||
|
||||
// Expand path before validation and storage
|
||||
char *expanded_path = chroma_expand_path(value);
|
||||
const char *path_to_validate = expanded_path ? expanded_path : value;
|
||||
|
|
@ -204,8 +339,9 @@ static int parse_config_line(chroma_config_t *config, char *line,
|
|||
return CHROMA_OK;
|
||||
}
|
||||
|
||||
if (add_output_mapping(config, output_name, path_to_validate) !=
|
||||
CHROMA_OK) {
|
||||
if (add_output_mapping(config, output_name, path_to_validate,
|
||||
config->default_scale_mode,
|
||||
config->default_filter_quality) != CHROMA_OK) {
|
||||
chroma_log("ERROR", "Failed to add output mapping: %s -> %s", output_name,
|
||||
path_to_validate);
|
||||
if (expanded_path) {
|
||||
|
|
@ -348,6 +484,37 @@ const char *chroma_config_get_image_for_output(chroma_config_t *config,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Get configuration mapping for output, including scale mode and filter
|
||||
// quality
|
||||
int chroma_config_get_mapping_for_output(
|
||||
chroma_config_t *config, const char *output_name,
|
||||
chroma_scale_mode_t *scale_mode, chroma_filter_quality_t *filter_quality) {
|
||||
if (!config || !output_name || !scale_mode || !filter_quality) {
|
||||
return CHROMA_ERROR_INIT;
|
||||
}
|
||||
|
||||
// Look for specific output mapping
|
||||
for (int i = 0; i < config->mapping_count; i++) {
|
||||
if (strcmp(config->mappings[i].output_name, output_name) == 0) {
|
||||
*scale_mode = config->mappings[i].scale_mode;
|
||||
*filter_quality = config->mappings[i].filter_quality;
|
||||
chroma_log("DEBUG",
|
||||
"Found specific mapping for output %s: scale=%s, filter=%s",
|
||||
output_name, scale_mode_to_string(*scale_mode),
|
||||
filter_quality_to_string(*filter_quality));
|
||||
return CHROMA_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Return defaults if no specific mapping found
|
||||
*scale_mode = config->default_scale_mode;
|
||||
*filter_quality = config->default_filter_quality;
|
||||
chroma_log("DEBUG", "Using defaults for output %s: scale=%s, filter=%s",
|
||||
output_name, scale_mode_to_string(*scale_mode),
|
||||
filter_quality_to_string(*filter_quality));
|
||||
return CHROMA_OK;
|
||||
}
|
||||
|
||||
// Create a sample configuration file
|
||||
int chroma_config_create_sample(const char *config_file) {
|
||||
if (!config_file) {
|
||||
|
|
@ -391,14 +558,24 @@ void chroma_config_print(const chroma_config_t *config) {
|
|||
chroma_log("INFO", "=== Configuration ===");
|
||||
chroma_log("INFO", "Default image: %s", config->default_image);
|
||||
chroma_log("INFO", "Daemon mode: %s", config->daemon_mode ? "true" : "false");
|
||||
chroma_log("INFO", "Default scale mode: %s",
|
||||
scale_mode_to_string(config->default_scale_mode));
|
||||
chroma_log("INFO", "Default filter quality: %s",
|
||||
filter_quality_to_string(config->default_filter_quality));
|
||||
chroma_log("INFO", "Output mappings: %d", config->mapping_count);
|
||||
|
||||
for (int i = 0; i < config->mapping_count; i++) {
|
||||
chroma_log("INFO", " %s -> %s", config->mappings[i].output_name,
|
||||
config->mappings[i].image_path);
|
||||
chroma_log("INFO", " %s -> %s (scale: %s, filter: %s)",
|
||||
config->mappings[i].output_name, config->mappings[i].image_path,
|
||||
scale_mode_to_string(config->mappings[i].scale_mode),
|
||||
filter_quality_to_string(config->mappings[i].filter_quality));
|
||||
chroma_log(
|
||||
"TRACE", " Mapping %d: output='%s', image='%s', path_exists=%s", i,
|
||||
config->mappings[i].output_name, config->mappings[i].image_path,
|
||||
"TRACE",
|
||||
" Mapping %d: output='%s', image='%s', scale='%s', filter='%s', "
|
||||
"path_exists=%s",
|
||||
i, config->mappings[i].output_name, config->mappings[i].image_path,
|
||||
scale_mode_to_string(config->mappings[i].scale_mode),
|
||||
filter_quality_to_string(config->mappings[i].filter_quality),
|
||||
chroma_path_exists(config->mappings[i].image_path) ? "yes" : "no");
|
||||
}
|
||||
chroma_log("INFO", "====================");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue