diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-07-27 11:19:42 -0400 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-01 22:47:54 -0400 |
commit | a4f7bf23b21d0d838a8a19261d5fd69719003a03 (patch) | |
tree | e46a226d8c3ded2d93e1933323263b6756199a68 /swaynag/main.c | |
parent | Support a detailed message in swaynagbar (diff) | |
download | sway-a4f7bf23b21d0d838a8a19261d5fd69719003a03.tar.gz sway-a4f7bf23b21d0d838a8a19261d5fd69719003a03.tar.zst sway-a4f7bf23b21d0d838a8a19261d5fd69719003a03.zip |
Address first round review for swaynag
Diffstat (limited to 'swaynag/main.c')
-rw-r--r-- | swaynag/main.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/swaynag/main.c b/swaynag/main.c new file mode 100644 index 00000000..60560c72 --- /dev/null +++ b/swaynag/main.c | |||
@@ -0,0 +1,246 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <getopt.h> | ||
3 | #include <signal.h> | ||
4 | #include "log.h" | ||
5 | #include "list.h" | ||
6 | #include "readline.h" | ||
7 | #include "swaynag/nagbar.h" | ||
8 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||
9 | |||
10 | static struct sway_nagbar nagbar; | ||
11 | |||
12 | void sig_handler(int signal) { | ||
13 | nagbar_destroy(&nagbar); | ||
14 | exit(EXIT_FAILURE); | ||
15 | } | ||
16 | |||
17 | void sway_terminate(int code) { | ||
18 | nagbar_destroy(&nagbar); | ||
19 | exit(code); | ||
20 | } | ||
21 | |||
22 | static void set_nagbar_colors() { | ||
23 | if (nagbar.type == NAGBAR_ERROR) { | ||
24 | nagbar.colors.button_background = 0x680A0AFF; | ||
25 | nagbar.colors.background = 0x900000FF; | ||
26 | nagbar.colors.text = 0xFFFFFFFF; | ||
27 | nagbar.colors.border = 0xD92424FF; | ||
28 | nagbar.colors.border_bottom = 0x470909FF; | ||
29 | } else if (nagbar.type == NAGBAR_WARNING) { | ||
30 | nagbar.colors.button_background = 0xFFC100FF; | ||
31 | nagbar.colors.background = 0xFFA800FF; | ||
32 | nagbar.colors.text = 0x000000FF; | ||
33 | nagbar.colors.border = 0xAB7100FF; | ||
34 | nagbar.colors.border_bottom = 0xAB7100FF; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | static char *read_from_stdin() { | ||
39 | char *buffer = NULL; | ||
40 | while (!feof(stdin)) { | ||
41 | char *line = read_line(stdin); | ||
42 | if (!line) { | ||
43 | continue; | ||
44 | } | ||
45 | |||
46 | if (!buffer) { | ||
47 | buffer = strdup(line); | ||
48 | } else { | ||
49 | buffer = realloc(buffer, strlen(buffer) + strlen(line) + 2); | ||
50 | strcat(buffer, line); | ||
51 | strcat(buffer, "\n"); | ||
52 | } | ||
53 | |||
54 | free(line); | ||
55 | } | ||
56 | |||
57 | if (buffer && buffer[strlen(buffer) - 1] == '\n') { | ||
58 | buffer[strlen(buffer) - 1] = '\0'; | ||
59 | } | ||
60 | |||
61 | return buffer; | ||
62 | } | ||
63 | |||
64 | int main(int argc, char **argv) { | ||
65 | int exit_code = EXIT_SUCCESS; | ||
66 | bool debug = false; | ||
67 | |||
68 | memset(&nagbar, 0, sizeof(nagbar)); | ||
69 | nagbar.anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ||
70 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ||
71 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||
72 | nagbar.type = NAGBAR_ERROR; | ||
73 | set_nagbar_colors(); | ||
74 | nagbar.font = strdup("pango:monospace 10"); | ||
75 | nagbar.buttons = create_list(); | ||
76 | |||
77 | struct sway_nagbar_button *button_close = | ||
78 | calloc(sizeof(struct sway_nagbar_button), 1); | ||
79 | button_close->text = strdup("X"); | ||
80 | button_close->type = NAGBAR_ACTION_DISMISS; | ||
81 | list_add(nagbar.buttons, button_close); | ||
82 | |||
83 | struct sway_nagbar_button *button_details = | ||
84 | calloc(sizeof(struct sway_nagbar_button), 1); | ||
85 | button_details->text = strdup("Toggle Details"); | ||
86 | button_details->type = NAGBAR_ACTION_EXPAND; | ||
87 | |||
88 | static struct option opts[] = { | ||
89 | {"button", required_argument, NULL, 'b'}, | ||
90 | {"debug", no_argument, NULL, 'd'}, | ||
91 | {"edge", required_argument, NULL, 'e'}, | ||
92 | {"font", required_argument, NULL, 'f'}, | ||
93 | {"help", no_argument, NULL, 'h'}, | ||
94 | {"detailed-message", no_argument, NULL, 'l'}, | ||
95 | {"detailed-button", required_argument, NULL, 'L'}, | ||
96 | {"message", required_argument, NULL, 'm'}, | ||
97 | {"output", required_argument, NULL, 'o'}, | ||
98 | {"dismiss-button", required_argument, NULL, 's'}, | ||
99 | {"type", required_argument, NULL, 't'}, | ||
100 | {"version", no_argument, NULL, 'v'}, | ||
101 | {0, 0, 0, 0} | ||
102 | }; | ||
103 | |||
104 | const char *usage = | ||
105 | "Usage: swaynag [options...]\n" | ||
106 | "\n" | ||
107 | " -b, --button <text> <action> Create a button with text that " | ||
108 | "executes action when pressed. Multiple buttons can be defined.\n" | ||
109 | " -d, --debug Enable debugging.\n" | ||
110 | " -e, --edge top|bottom Set the edge to use.\n" | ||
111 | " -f, --font <font> Set the font to use.\n" | ||
112 | " -h, --help Show help message and quit.\n" | ||
113 | " -l, --detailed-message Read a detailed message from stdin.\n" | ||
114 | " -L, --detailed-button <text> Set the text of the detail button.\n" | ||
115 | " -m, --message <msg> Set the message text.\n" | ||
116 | " -o, --output <output> Set the output to use.\n" | ||
117 | " -s, --dismiss-button <text> Set the dismiss button text.\n" | ||
118 | " -t, --type error|warning Set the message type.\n" | ||
119 | " -v, --version Show the version number and quit.\n"; | ||
120 | |||
121 | while (1) { | ||
122 | int c = getopt_long(argc, argv, "b:de:f:hlL:m:o:s:t:v", opts, NULL); | ||
123 | if (c == -1) { | ||
124 | break; | ||
125 | } | ||
126 | switch (c) { | ||
127 | case 'b': // Button | ||
128 | if (optind >= argc) { | ||
129 | fprintf(stderr, "Missing action for button %s\n", optarg); | ||
130 | exit_code = EXIT_FAILURE; | ||
131 | goto cleanup; | ||
132 | } | ||
133 | struct sway_nagbar_button *button; | ||
134 | button = calloc(sizeof(struct sway_nagbar_button), 1); | ||
135 | button->text = strdup(optarg); | ||
136 | button->type = NAGBAR_ACTION_COMMAND; | ||
137 | button->action = strdup(argv[optind]); | ||
138 | optind++; | ||
139 | list_add(nagbar.buttons, button); | ||
140 | break; | ||
141 | case 'd': // Debug | ||
142 | debug = true; | ||
143 | break; | ||
144 | case 'e': // Edge | ||
145 | if (strcmp(optarg, "top") == 0) { | ||
146 | nagbar.anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ||
147 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ||
148 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||
149 | } else if (strcmp(optarg, "bottom") == 0) { | ||
150 | nagbar.anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ||
151 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ||
152 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||
153 | } else { | ||
154 | fprintf(stderr, "Invalid edge: %s\n", optarg); | ||
155 | exit_code = EXIT_FAILURE; | ||
156 | goto cleanup; | ||
157 | } | ||
158 | break; | ||
159 | case 'f': // Font | ||
160 | free(nagbar.font); | ||
161 | nagbar.font = strdup(optarg); | ||
162 | break; | ||
163 | case 'l': // Detailed Message | ||
164 | free(nagbar.details.message); | ||
165 | nagbar.details.message = read_from_stdin(); | ||
166 | nagbar.details.button_up.text = strdup("▲"); | ||
167 | nagbar.details.button_down.text = strdup("▼"); | ||
168 | break; | ||
169 | case 'L': // Detailed Button Text | ||
170 | free(button_details->text); | ||
171 | button_details->text = strdup(optarg); | ||
172 | break; | ||
173 | case 'm': // Message | ||
174 | free(nagbar.message); | ||
175 | nagbar.message = strdup(optarg); | ||
176 | break; | ||
177 | case 'o': // Output | ||
178 | free(nagbar.output.name); | ||
179 | nagbar.output.name = strdup(optarg); | ||
180 | break; | ||
181 | case 's': // Dismiss Button Text | ||
182 | free(button_close->text); | ||
183 | button_close->text = strdup(optarg); | ||
184 | break; | ||
185 | case 't': // Type | ||
186 | if (strcmp(optarg, "error") == 0) { | ||
187 | nagbar.type = NAGBAR_ERROR; | ||
188 | } else if (strcmp(optarg, "warning") == 0) { | ||
189 | nagbar.type = NAGBAR_WARNING; | ||
190 | } else { | ||
191 | fprintf(stderr, "Type must be either 'error' or 'warning'\n"); | ||
192 | exit_code = EXIT_FAILURE; | ||
193 | goto cleanup; | ||
194 | } | ||
195 | set_nagbar_colors(); | ||
196 | break; | ||
197 | case 'v': // Version | ||
198 | fprintf(stdout, "swaynag version " SWAY_VERSION "\n"); | ||
199 | exit_code = EXIT_SUCCESS; | ||
200 | goto cleanup; | ||
201 | default: // Help or unknown flag | ||
202 | fprintf(c == 'h' ? stdout : stderr, "%s", usage); | ||
203 | exit_code = c == 'h' ? EXIT_SUCCESS : EXIT_FAILURE; | ||
204 | goto cleanup; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | wlr_log_init(debug ? WLR_DEBUG : WLR_ERROR, NULL); | ||
209 | |||
210 | if (!nagbar.message) { | ||
211 | wlr_log(WLR_ERROR, "No message passed. Please provide --message/-m"); | ||
212 | exit_code = EXIT_FAILURE; | ||
213 | goto cleanup; | ||
214 | } | ||
215 | |||
216 | if (nagbar.details.message) { | ||
217 | list_add(nagbar.buttons, button_details); | ||
218 | } else { | ||
219 | free(button_details->text); | ||
220 | free(button_details); | ||
221 | } | ||
222 | |||
223 | wlr_log(WLR_DEBUG, "Output: %s", nagbar.output.name); | ||
224 | wlr_log(WLR_DEBUG, "Anchors: %d", nagbar.anchors); | ||
225 | wlr_log(WLR_DEBUG, "Type: %d", nagbar.type); | ||
226 | wlr_log(WLR_DEBUG, "Message: %s", nagbar.message); | ||
227 | wlr_log(WLR_DEBUG, "Font: %s", nagbar.font); | ||
228 | wlr_log(WLR_DEBUG, "Buttons"); | ||
229 | for (int i = 0; i < nagbar.buttons->length; i++) { | ||
230 | struct sway_nagbar_button *button = nagbar.buttons->items[i]; | ||
231 | wlr_log(WLR_DEBUG, "\t[%s] `%s`", button->text, button->action); | ||
232 | } | ||
233 | |||
234 | signal(SIGTERM, sig_handler); | ||
235 | |||
236 | nagbar_setup(&nagbar); | ||
237 | nagbar_run(&nagbar); | ||
238 | return exit_code; | ||
239 | |||
240 | cleanup: | ||
241 | free(button_details->text); | ||
242 | free(button_details); | ||
243 | nagbar_destroy(&nagbar); | ||
244 | return exit_code; | ||
245 | } | ||
246 | |||