diff --git a/README.md b/README.md index b8beef59..0af0b8b9 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,17 @@ Examples: - `PgUp` or `p`: Open previous file; - `Esc`, `Enter`, `F10` or `q`: Exit the program. +## Configuration + +The viewer searches for the configuration file with name `config` in the +following directories: +- `$XDG_CONFIG_HOME/swayimg` +- `$HOME/.config/swayimg` + +Sample file is available [here](https://github.com/artemsen/swayimg/blob/master/extra/swayimgrc). + +See `man swayimgrc` for details. + ## Build and install ``` diff --git a/extra/swayimg.1 b/extra/swayimg.1 index 1fb8b374..5376d91d 100644 --- a/extra/swayimg.1 +++ b/extra/swayimg.1 @@ -75,6 +75,9 @@ Exit the program. .SH ENVIRONMENT .IP \fISWAYSOCK\fR Path to the socket file used for Sway IPC. +.\" related man pages +.SH SEE ALSO +swayimgrc(5) .\" link to homepage .SH BUGS For suggestions, comments, bug reports etc. visit the diff --git a/extra/swayimgrc b/extra/swayimgrc new file mode 100644 index 00000000..f5e8a82b --- /dev/null +++ b/extra/swayimgrc @@ -0,0 +1,21 @@ +# Swayimg configuration file. + +# This file contains the default configuration. +# The viewer searches for the config file in the following locations: +# 1. $XDG_CONFIG_HOME/swayimg/config +# 2. $HOME/.config/swayimg/config +# See `man swayimgrc` for details. + +# Initial scale (default, fit, or real) +scale = default + +# Start in full screen mode (yes/no) +fullscreen = no + +# Background mode/color (grid or RGB, e.g. 112233) +background = grid + +# Show image info: format, size, EXIF, and current scale (yes/no) +info = no + +# vim: filetype=dosini diff --git a/extra/swayimgrc.5 b/extra/swayimgrc.5 new file mode 100644 index 00000000..eefccad1 --- /dev/null +++ b/extra/swayimgrc.5 @@ -0,0 +1,50 @@ +.\" Swayimg configuration file format. +.\" Copyright (C) 2022 Artem Senichev +.TH SWAYIMG 5 2022-02-09 swayimg "Swayimg configuration" +.SH NAME +swayimgrc \- Swayimg configuration file +.\" possible file locations +.SH SYNOPSIS +.SY \fI$XDG_CONFIG_HOME\fR/swayimg/config +.SY \fI$HOME\fR/.config/swayimg/config +.\" format description +.SH DESCRIPTION +.SS General format description +The Swayimg configuration file is a text-based INI file used to override the +default settings. +.PP +The basic element contained in the INI file is the key or property. +Every key has a name and a value, delimited by an equals sign (=). +The name appears to the left of the equals sign. The value can contain any +character. Kay and values are case sensitive. +.PP +The number sign (#) at the beginning of the line indicates a comment. +Empty lines and comments are ignored. +.SS Properties +.PP +.IP "\fBscale\fR: initial image scale:" +.nf +\fIdefault\fR: 100% or less to fit to window; +\fIfit\fR: fit to window; +\fIreal\fR: real size (100%); +.IP "\fBfullscreen\fR: start in dull screen mode, possible values are \fIyes\fR or \fIno\fR" +.IP "\fBbackground\fR: background mode or color, possible values are \fIgrid\fR or RGB hex color (e.g. \fI1a2b3c\fR)" +.IP "\fBinfo\fR: show image meta information: format, size, EXIF, and current scale, possible values are \fIyes\fR or \fIno\fR" +.\" example file +.SH EXAMPLES +.EX +# comment +scale = default +fullscreen = no +background = grid +info = no +.EE +.\" related man pages +.SH SEE ALSO +swayimg(1) +.\" link to homepage +.SH BUGS +For suggestions, comments, bug reports etc. visit the +.UR https://github.com/artemsen/swayimg +project homepage +.UE . diff --git a/meson.build b/meson.build index 0d4714c2..ebe737a0 100644 --- a/meson.build +++ b/meson.build @@ -82,6 +82,7 @@ xdg_shell_h = custom_target( # man installation if get_option('man') install_man('extra/swayimg.1') + install_man('extra/swayimgrc.5') endif # desktop file + icon diff --git a/src/canvas.h b/src/canvas.h index 3e8c0f26..91db3e9f 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -7,7 +7,7 @@ #include #include -// Special bacground color: grid +// Grid background mode id #define BACKGROUND_GRID UINT32_MAX // Convert color components from RGB to float diff --git a/src/config.c b/src/config.c index 562c15fc..5f53d7ca 100644 --- a/src/config.c +++ b/src/config.c @@ -5,17 +5,137 @@ #include #include +#include #include #include +#include config_t config = { .scale = scale_fit_or100, .background = BACKGROUND_GRID, }; +/** + * Apply property to configuration. + * @param[in] key property key + * @param[in] value property value + */ +static void apply_conf(const char* key, const char* value) +{ + const char* yes = "yes"; + const char* no = "no"; + + if (strcmp(key, "scale") == 0) { + if (strcmp(value, "default") == 0) { + config.scale = scale_fit_or100; + } else if (strcmp(value, "fit") == 0) { + config.scale = scale_fit_window; + } else if (strcmp(value, "real") == 0) { + config.scale = scale_100; + } + } else if (strcmp(key, "fullscreen") == 0) { + if (strcmp(value, yes) == 0) { + config.fullscreen = true; + } else if (strcmp(value, no) == 0) { + config.fullscreen = false; + } + } else if (strcmp(key, "background") == 0) { + set_background(value); + } else if (strcmp(key, "info") == 0) { + if (strcmp(value, yes) == 0) { + config.show_info = true; + } else if (strcmp(value, no) == 0) { + config.show_info = false; + } + } +} + +/** + * Open user's configuration file. + * @return file descriptior or NULL on errors + */ +static FILE* open_file(void) +{ + char path[64]; + size_t len; + const char* postfix = "/swayimg/config"; + const size_t postfix_len = strlen(postfix); + + const char* config_dir = getenv("XDG_CONFIG_HOME"); + if (config_dir) { + len = strlen(config_dir); + if (len < sizeof(path)) { + memcpy(path, config_dir, len + 1 /*last null*/); + } else { + len = 0; + } + } else { + config_dir = getenv("HOME"); + len = config_dir ? strlen(config_dir) : 0; + if (len && len < sizeof(path)) { + memcpy(path, config_dir, len + 1 /*last null*/); + const char* dir = "/.config"; + const size_t dlen = strlen(dir); + if (len + dlen < sizeof(path)) { + memcpy(path + len, dir, dlen + 1 /*last null*/); + len += dlen; + } else { + len = 0; + } + } + } + + if (len && len + postfix_len < sizeof(path)) { + memcpy(path + len, postfix, postfix_len + 1 /*last null*/); + return fopen(path, "r"); + } + return NULL; +} + void load_config(void) { - // todo + char* buff = NULL; + size_t buff_sz = 0; + ssize_t nread; + + FILE* fd = open_file(); + if (!fd) { + return; + } + + while ((nread = getline(&buff, &buff_sz, fd)) != -1) { + const char* value; + char* delim; + char* line = buff; + // trim spaces + while (nread-- && isspace(line[nread])) { + line[nread] = 0; + } + while (*line && isspace(*line)) { + ++line; + } + if (!*line || *line == '#') { + continue; // skip empty lines and comments + } + delim = strchr(line, '='); + if (!delim) { + continue; // invalid format: delimiter not found + } + // trim spaces from start of value + value = delim + 1; + while (*value && isspace(*value)) { + ++value; + } + // trim spaces from key + *delim = 0; + while (line != delim && isspace(*--delim)) { + *delim = 0; + } + apply_conf(line, value); + } + + free(buff); + fclose(fd); } bool set_scale(const char* value) diff --git a/src/config.h b/src/config.h index f5018ed0..19950489 100644 --- a/src/config.h +++ b/src/config.h @@ -9,7 +9,7 @@ typedef struct { scale_t scale; ///< Initial scale rect_t window; ///< Window geometry - uint32_t background; ///< Background color + uint32_t background; ///< Background mode/color bool fullscreen; ///< Full screen mode bool show_info; ///< Show image info } config_t; diff --git a/src/main.c b/src/main.c index 56ad7f43..b5dead10 100644 --- a/src/main.c +++ b/src/main.c @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) case 'b': if (!set_background(optarg)) { fprintf(stderr, "Invalid background: %s\n", optarg); - fprintf(stderr, "Expected \"grid\" or RGB hex value.\n"); + fprintf(stderr, "Expected 'grid' or RGB hex value.\n"); return EXIT_FAILURE; } break;