summaryrefslogtreecommitdiffstats
path: root/sway/commands/output/background.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/output/background.c')
-rw-r--r--sway/commands/output/background.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c
new file mode 100644
index 00000000..f039c9c9
--- /dev/null
+++ b/sway/commands/output/background.c
@@ -0,0 +1,105 @@
1#define _XOPEN_SOURCE 500
2#include <libgen.h>
3#include <strings.h>
4#include <unistd.h>
5#include <wordexp.h>
6#include "sway/commands.h"
7#include "sway/config.h"
8#include "log.h"
9#include "stringop.h"
10
11static char *bg_options[] = {
12 "stretch",
13 "center",
14 "fill",
15 "fit",
16 "tile",
17};
18
19struct cmd_results *output_cmd_background(int argc, char **argv) {
20 if (!config->handler_context.output_config) {
21 return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
22 }
23 if (!argc) {
24 return cmd_results_new(CMD_INVALID, "output",
25 "Missing background file or color specification.");
26 }
27 if (argc < 2) {
28 return cmd_results_new(CMD_INVALID, "output",
29 "Missing background scaling mode or `solid_color`.");
30 }
31
32 struct output_config *output = config->handler_context.output_config;
33
34 if (strcasecmp(argv[1], "solid_color") == 0) {
35 output->background = calloc(1, strlen(argv[0]) + 3);
36 snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]);
37 output->background_option = strdup("solid_color");
38 argc -= 2; argv += 2;
39 } else {
40 bool valid = false;
41 char *mode;
42 size_t j;
43 for (j = 0; j < (size_t)argc; ++j) {
44 mode = argv[j];
45 size_t n = sizeof(bg_options) / sizeof(char *);
46 for (size_t k = 0; k < n; ++k) {
47 if (strcasecmp(mode, bg_options[k]) == 0) {
48 valid = true;
49 break;
50 }
51 }
52 if (valid) {
53 break;
54 }
55 }
56 if (!valid) {
57 return cmd_results_new(CMD_INVALID, "output",
58 "Missing background scaling mode.");
59 }
60
61 wordexp_t p;
62 char *src = join_args(argv, j);
63 if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
64 return cmd_results_new(CMD_INVALID, "output",
65 "Invalid syntax (%s).", src);
66 }
67 free(src);
68 src = p.we_wordv[0];
69 if (config->reading && *src != '/') {
70 char *conf = strdup(config->current_config);
71 if (conf) {
72 char *conf_path = dirname(conf);
73 src = malloc(strlen(conf_path) + strlen(src) + 2);
74 if (src) {
75 sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
76 } else {
77 wlr_log(L_ERROR,
78 "Unable to allocate background source");
79 }
80 free(conf);
81 } else {
82 wlr_log(L_ERROR, "Unable to allocate background source");
83 }
84 }
85 if (!src || access(src, F_OK) == -1) {
86 wordfree(&p);
87 return cmd_results_new(CMD_INVALID, "output",
88 "Background file unreadable (%s).", src);
89 }
90
91 output->background = strdup(src);
92 output->background_option = strdup(mode);
93 if (src != p.we_wordv[0]) {
94 free(src);
95 }
96 wordfree(&p);
97
98 argc -= j + 1; argv += j + 1;
99 }
100
101 config->handler_context.leftovers.argc = argc;
102 config->handler_context.leftovers.argv = argv;
103 return NULL;
104}
105