diff options
Diffstat (limited to 'swaynag/config.c')
-rw-r--r-- | swaynag/config.c | 104 |
1 files changed, 73 insertions, 31 deletions
diff --git a/swaynag/config.c b/swaynag/config.c index ca7f4eb2..efd71ce7 100644 --- a/swaynag/config.c +++ b/swaynag/config.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <getopt.h> | 1 | #include <getopt.h> |
3 | #include <stdio.h> | 2 | #include <stdio.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -11,24 +10,40 @@ | |||
11 | #include "util.h" | 10 | #include "util.h" |
12 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 11 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
13 | 12 | ||
14 | static char *read_from_stdin(void) { | 13 | static char *read_and_trim_stdin(void) { |
15 | char *buffer = NULL; | 14 | char *buffer = NULL, *line = NULL; |
16 | size_t buffer_len = 0; | 15 | size_t buffer_len = 0, line_size = 0; |
17 | char *line = NULL; | 16 | while (1) { |
18 | size_t line_size = 0; | 17 | ssize_t nread = getline(&line, &line_size, stdin); |
19 | ssize_t nread; | 18 | if (nread == -1) { |
20 | while ((nread = getline(&line, &line_size, stdin)) != -1) { | 19 | if (feof(stdin)) { |
20 | break; | ||
21 | } else { | ||
22 | perror("getline"); | ||
23 | goto freeline; | ||
24 | } | ||
25 | } | ||
21 | buffer = realloc(buffer, buffer_len + nread + 1); | 26 | buffer = realloc(buffer, buffer_len + nread + 1); |
22 | snprintf(&buffer[buffer_len], nread + 1, "%s", line); | 27 | if (!buffer) { |
28 | perror("realloc"); | ||
29 | goto freebuf; | ||
30 | } | ||
31 | memcpy(&buffer[buffer_len], line, nread + 1); | ||
23 | buffer_len += nread; | 32 | buffer_len += nread; |
24 | } | 33 | } |
25 | free(line); | 34 | free(line); |
26 | 35 | ||
27 | while (buffer && buffer[buffer_len - 1] == '\n') { | 36 | while (buffer_len && buffer[buffer_len - 1] == '\n') { |
28 | buffer[--buffer_len] = '\0'; | 37 | buffer[--buffer_len] = '\0'; |
29 | } | 38 | } |
30 | 39 | ||
31 | return buffer; | 40 | return buffer; |
41 | |||
42 | freeline: | ||
43 | free(line); | ||
44 | freebuf: | ||
45 | free(buffer); | ||
46 | return NULL; | ||
32 | } | 47 | } |
33 | 48 | ||
34 | int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | 49 | int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, |
@@ -51,7 +66,7 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
51 | TO_PADDING_BTN, | 66 | TO_PADDING_BTN, |
52 | }; | 67 | }; |
53 | 68 | ||
54 | static struct option opts[] = { | 69 | static const struct option opts[] = { |
55 | {"button", required_argument, NULL, 'b'}, | 70 | {"button", required_argument, NULL, 'b'}, |
56 | {"button-no-terminal", required_argument, NULL, 'B'}, | 71 | {"button-no-terminal", required_argument, NULL, 'B'}, |
57 | {"button-dismiss", required_argument, NULL, 'z'}, | 72 | {"button-dismiss", required_argument, NULL, 'z'}, |
@@ -59,6 +74,7 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
59 | {"config", required_argument, NULL, 'c'}, | 74 | {"config", required_argument, NULL, 'c'}, |
60 | {"debug", no_argument, NULL, 'd'}, | 75 | {"debug", no_argument, NULL, 'd'}, |
61 | {"edge", required_argument, NULL, 'e'}, | 76 | {"edge", required_argument, NULL, 'e'}, |
77 | {"layer", required_argument, NULL, 'y'}, | ||
62 | {"font", required_argument, NULL, 'f'}, | 78 | {"font", required_argument, NULL, 'f'}, |
63 | {"help", no_argument, NULL, 'h'}, | 79 | {"help", no_argument, NULL, 'h'}, |
64 | {"detailed-message", no_argument, NULL, 'l'}, | 80 | {"detailed-message", no_argument, NULL, 'l'}, |
@@ -104,6 +120,8 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
104 | " -c, --config <path> Path to config file.\n" | 120 | " -c, --config <path> Path to config file.\n" |
105 | " -d, --debug Enable debugging.\n" | 121 | " -d, --debug Enable debugging.\n" |
106 | " -e, --edge top|bottom Set the edge to use.\n" | 122 | " -e, --edge top|bottom Set the edge to use.\n" |
123 | " -y, --layer overlay|top|bottom|background\n" | ||
124 | " Set the layer to use.\n" | ||
107 | " -f, --font <font> Set the font to use.\n" | 125 | " -f, --font <font> Set the font to use.\n" |
108 | " -h, --help Show help message and quit.\n" | 126 | " -h, --help Show help message and quit.\n" |
109 | " -l, --detailed-message Read a detailed message from stdin.\n" | 127 | " -l, --detailed-message Read a detailed message from stdin.\n" |
@@ -133,7 +151,7 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
133 | 151 | ||
134 | optind = 1; | 152 | optind = 1; |
135 | while (1) { | 153 | while (1) { |
136 | int c = getopt_long(argc, argv, "b:B:z:Z:c:de:f:hlL:m:o:s:t:v", opts, NULL); | 154 | int c = getopt_long(argc, argv, "b:B:z:Z:c:de:y:f:hlL:m:o:s:t:v", opts, NULL); |
137 | if (c == -1) { | 155 | if (c == -1) { |
138 | break; | 156 | break; |
139 | } | 157 | } |
@@ -147,8 +165,11 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
147 | fprintf(stderr, "Missing action for button %s\n", optarg); | 165 | fprintf(stderr, "Missing action for button %s\n", optarg); |
148 | return EXIT_FAILURE; | 166 | return EXIT_FAILURE; |
149 | } | 167 | } |
150 | struct swaynag_button *button; | 168 | struct swaynag_button *button = calloc(1, sizeof(struct swaynag_button)); |
151 | button = calloc(sizeof(struct swaynag_button), 1); | 169 | if (!button) { |
170 | perror("calloc"); | ||
171 | return EXIT_FAILURE; | ||
172 | } | ||
152 | button->text = strdup(optarg); | 173 | button->text = strdup(optarg); |
153 | button->type = SWAYNAG_ACTION_COMMAND; | 174 | button->type = SWAYNAG_ACTION_COMMAND; |
154 | button->action = strdup(argv[optind]); | 175 | button->action = strdup(argv[optind]); |
@@ -184,24 +205,45 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
184 | } | 205 | } |
185 | } | 206 | } |
186 | break; | 207 | break; |
208 | case 'y': // Layer | ||
209 | if (type) { | ||
210 | if (strcmp(optarg, "background") == 0) { | ||
211 | type->layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; | ||
212 | } else if (strcmp(optarg, "bottom") == 0) { | ||
213 | type->layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; | ||
214 | } else if (strcmp(optarg, "top") == 0) { | ||
215 | type->layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP; | ||
216 | } else if (strcmp(optarg, "overlay") == 0) { | ||
217 | type->layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; | ||
218 | } else { | ||
219 | fprintf(stderr, "Invalid layer: %s\n" | ||
220 | "Usage: --layer overlay|top|bottom|background\n", | ||
221 | optarg); | ||
222 | return EXIT_FAILURE; | ||
223 | } | ||
224 | } | ||
225 | break; | ||
187 | case 'f': // Font | 226 | case 'f': // Font |
188 | if (type) { | 227 | if (type) { |
189 | free(type->font); | 228 | pango_font_description_free(type->font_description); |
190 | type->font = strdup(optarg); | 229 | type->font_description = pango_font_description_from_string(optarg); |
191 | } | 230 | } |
192 | break; | 231 | break; |
193 | case 'l': // Detailed Message | 232 | case 'l': // Detailed Message |
194 | if (swaynag) { | 233 | if (swaynag) { |
195 | free(swaynag->details.message); | 234 | free(swaynag->details.message); |
196 | swaynag->details.message = read_from_stdin(); | 235 | swaynag->details.message = read_and_trim_stdin(); |
236 | if (!swaynag->details.message) { | ||
237 | return EXIT_FAILURE; | ||
238 | } | ||
197 | swaynag->details.button_up.text = strdup("▲"); | 239 | swaynag->details.button_up.text = strdup("▲"); |
198 | swaynag->details.button_down.text = strdup("▼"); | 240 | swaynag->details.button_down.text = strdup("▼"); |
199 | } | 241 | } |
200 | break; | 242 | break; |
201 | case 'L': // Detailed Button Text | 243 | case 'L': // Detailed Button Text |
202 | if (swaynag) { | 244 | if (swaynag) { |
203 | free(swaynag->details.button_details->text); | 245 | free(swaynag->details.details_text); |
204 | swaynag->details.button_details->text = strdup(optarg); | 246 | swaynag->details.details_text = strdup(optarg); |
205 | } | 247 | } |
206 | break; | 248 | break; |
207 | case 'm': // Message | 249 | case 'm': // Message |
@@ -218,8 +260,7 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, | |||
218 | break; | 260 | break; |
219 | case 's': // Dismiss Button Text | 261 | case 's': // Dismiss Button Text |
220 | if (swaynag) { | 262 | if (swaynag) { |
221 | struct swaynag_button *button_close; | 263 | struct swaynag_button *button_close = swaynag->buttons->items[0]; |
222 | button_close = swaynag->buttons->items[0]; | ||
223 | free(button_close->text); | 264 | free(button_close->text); |
224 | button_close->text = strdup(optarg); | 265 | button_close->text = strdup(optarg); |
225 | } | 266 | } |
@@ -378,23 +419,24 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) { | |||
378 | 419 | ||
379 | if (line[0] == '[') { | 420 | if (line[0] == '[') { |
380 | char *close = strchr(line, ']'); | 421 | char *close = strchr(line, ']'); |
381 | if (!close) { | 422 | if (!close || close != &line[nread - 2] || nread <= 3) { |
382 | fprintf(stderr, "Closing bracket not found on line %d\n", | 423 | fprintf(stderr, "Line %d is malformed\n", line_number); |
383 | line_number); | ||
384 | result = 1; | 424 | result = 1; |
385 | break; | 425 | break; |
386 | } | 426 | } |
387 | char *name = calloc(1, close - line); | 427 | *close = '\0'; |
388 | strncat(name, line + 1, close - line - 1); | 428 | type = swaynag_type_get(types, &line[1]); |
389 | type = swaynag_type_get(types, name); | ||
390 | if (!type) { | 429 | if (!type) { |
391 | type = swaynag_type_new(name); | 430 | type = swaynag_type_new(&line[1]); |
392 | list_add(types, type); | 431 | list_add(types, type); |
393 | } | 432 | } |
394 | free(name); | ||
395 | } else { | 433 | } else { |
396 | char *flag = malloc(sizeof(char) * (nread + 3)); | 434 | char *flag = malloc(nread + 3); |
397 | sprintf(flag, "--%s", line); | 435 | if (!flag) { |
436 | perror("calloc"); | ||
437 | return EXIT_FAILURE; | ||
438 | } | ||
439 | snprintf(flag, nread + 3, "--%s", line); | ||
398 | char *argv[] = {"swaynag", flag}; | 440 | char *argv[] = {"swaynag", flag}; |
399 | result = swaynag_parse_options(2, argv, swaynag, types, type, | 441 | result = swaynag_parse_options(2, argv, swaynag, types, type, |
400 | NULL, NULL); | 442 | NULL, NULL); |