From b3a43e226140d9b5d49c4ed24798e3f3006dcae5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 25 Aug 2017 08:06:38 -0400 Subject: [PATCH] add configuration file --- .gitignore | 1 + examples/config.c | 154 +++++++++++++++++++------------ examples/config.h | 1 + examples/wlr-example.ini.example | 33 +++++++ 4 files changed, 128 insertions(+), 61 deletions(-) create mode 100644 examples/wlr-example.ini.example diff --git a/.gitignore b/.gitignore index ce85118c..d4edde88 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ test/ build/ .lvimrc wayland-*-protocol.* +wlr-example.ini diff --git a/examples/config.c b/examples/config.c index 4f70faf0..bca2b44b 100644 --- a/examples/config.c +++ b/examples/config.c @@ -1,86 +1,88 @@ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif #include #include #include #include +#include +#include #include "shared.h" #include "config.h" +#include "ini.h" static void usage(const char *name, int ret) { fprintf(stderr, - "usage: %s [-d [-r | -f]]*\n" + "usage: %s [-C ]\n" "\n" - " -o The name of the DRM display. e.g. DVI-I-1.\n" - " -r The rotation counter clockwise. Valid values are 90, 180, 270.\n" - " -x The X-axis coordinate position of this output in the layout.\n" - " -y The Y-axis coordinate position of this output in the layout.\n" - " -f Flip the output along the vertical axis.\n", name); + " -C Path to the configuration file (default: wlr-example.ini).\n" + " See `examples/wlr-example.ini.example` for config file documentation.\n", name); exit(ret); } -struct example_config *parse_args(int argc, char *argv[]) { - struct example_config *config = calloc(1, sizeof(struct example_config)); - wl_list_init(&config->outputs); - struct output_config *oc = NULL; +static const char *output_prefix = "output:"; - int c; - while ((c = getopt(argc, argv, "o:r:x:y:fh")) != -1) { - switch (c) { - case 'o': - oc = calloc(1, sizeof(*oc)); - oc->name = optarg; - oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; - wl_list_insert(&config->outputs, &oc->link); - break; - case 'r': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } +static int config_ini_handler(void *user, const char *section, const char *name, const char *value) { + struct example_config *config = user; + if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { + const char *output_name = section + strlen(output_prefix); + struct output_config *oc; + bool found = false; - if (oc->transform != WL_OUTPUT_TRANSFORM_NORMAL - && oc->transform != WL_OUTPUT_TRANSFORM_FLIPPED) { - fprintf(stderr, "Rotation for %s already specified\n", oc->name); - usage(argv[0], 1); + wl_list_for_each(oc, &config->outputs, link) { + if (strcmp(oc->name, output_name) == 0) { + found = true; + break; } + } + + if (!found) { + oc = calloc(1, sizeof(struct output_config)); + oc->name = strdup(output_name); + oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; + wl_list_insert(&config->outputs, &oc->link); + } - if (strcmp(optarg, "90") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_90; - } else if (strcmp(optarg, "180") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_180; - } else if (strcmp(optarg, "270") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_270; + if (strcmp(name, "x") == 0) { + oc->x = strtol(value, NULL, 10); + } else if (strcmp(name, "y") == 0) { + oc->y = strtol(value, NULL, 10); + } else if (strcmp(name, "rotate") == 0) { + if (strcmp(value, "90") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_90; + } else if (strcmp(value, "180") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_180; + } else if (strcmp(value, "270") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_270; + } else if (strcmp(value, "flipped") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED; + } else if (strcmp(value, "flipped-90") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; + } else if (strcmp(value, "flipped-180") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180; + } else if (strcmp(value, "flipped-270") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; } else { - fprintf(stderr, "Invalid rotation '%s'\n", optarg); - usage(argv[0], 1); - } - break; - case 'x': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } - oc->x = strtol(optarg, NULL, 0); - break; - case 'y': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } - oc->y = strtol(optarg, NULL, 0); - break; - case 'f': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); + wlr_log(L_ERROR, "got unknown transform value: %s", value); } + } + } else { + wlr_log(L_ERROR, "got unknown config section: %s", section); + } - if (oc->transform >= WL_OUTPUT_TRANSFORM_FLIPPED) { - fprintf(stderr, "Flip for %s already specified\n", oc->name); - usage(argv[0], 1); - } + return 1; +} + +struct example_config *parse_args(int argc, char *argv[]) { + struct example_config *config = calloc(1, sizeof(struct example_config)); + wl_list_init(&config->outputs); - oc->transform += WL_OUTPUT_TRANSFORM_FLIPPED; + int c; + while ((c = getopt(argc, argv, "C:h")) != -1) { + switch (c) { + case 'C': + config->config_path = strdup(optarg); break; case 'h': case '?': @@ -88,14 +90,44 @@ struct example_config *parse_args(int argc, char *argv[]) { } } + if (!config->config_path) { + // get the config path from the current directory + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + char buf[1024]; + sprintf(buf, "%s/%s", cwd, "wlr-example.ini"); + config->config_path = strdup(buf); + } else { + wlr_log(L_ERROR, "could not get cwd"); + exit(1); + } + } + + int result = ini_parse(config->config_path, config_ini_handler, config); + + if (result == -1) { + wlr_log(L_ERROR, "Could not find config file at %s", config->config_path); + exit(1); + } else if (result == -2) { + wlr_log(L_ERROR, "Could not allocate memory to parse config file"); + exit(1); + } else if (result != 0) { + wlr_log(L_ERROR, "Could not parse config file"); + exit(1); + } + return config; } void example_config_destroy(struct example_config *config) { struct output_config *oc, *tmp = NULL; wl_list_for_each_safe(oc, tmp, &config->outputs, link) { + free(oc->name); free(oc); } + if (config->config_path) { + free(config->config_path); + } free(config); } diff --git a/examples/config.h b/examples/config.h index 1ecadd81..d02d1a2c 100644 --- a/examples/config.h +++ b/examples/config.h @@ -14,6 +14,7 @@ struct output_config { struct example_config { struct wl_list outputs; + char *config_path; }; struct example_config *parse_args(int argc, char *argv[]); diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example new file mode 100644 index 00000000..283439f0 --- /dev/null +++ b/examples/wlr-example.ini.example @@ -0,0 +1,33 @@ +# Configuration +# ------------- +# Some examples will read a configuration file. Not all examples will use all of +# the configuration options. The configuration file will be loaded from +# `wlr-example.ini` from the current directory or the path can be specified by the +# `-C` option given on the command line. +# +# Output configuration +# ~~~~~~~~~~~~~~~~~~~~ +# Each output is specified in a section named [output:{NAME}] where NAME is the +# drm name for this output. +# +# Value "x" specifies the x-coordinate in the output layout. +# +# Value "y" specifies the y-coordinate in the output layout. +# +# Value "rotate" specifies output rotation and can be 90, 180, 270, flipped, +# flipped-90, flipped-180, or flipped-270 +[output:HDMI-A-1] +x=3000 +y=0 +rotate=90 + +[output:DP-1] +x=0 +y=0 +rotate=270 + +[output:DVI-D-1] +x=1080 +y=232 + +# vim:filetype=dosini