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