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