aboutsummaryrefslogtreecommitdiffstats
path: root/swaynag/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaynag/config.c')
-rw-r--r--swaynag/config.c104
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
14static char *read_from_stdin(void) { 13static 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
42freeline:
43 free(line);
44freebuf:
45 free(buffer);
46 return NULL;
32} 47}
33 48
34int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, 49int 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);