diff options
Diffstat (limited to 'swaynag')
-rw-r--r-- | swaynag/config.c | 76 | ||||
-rw-r--r-- | swaynag/main.c | 50 | ||||
-rw-r--r-- | swaynag/meson.build | 3 | ||||
-rw-r--r-- | swaynag/render.c | 18 | ||||
-rw-r--r-- | swaynag/swaynag.c | 27 | ||||
-rw-r--r-- | swaynag/types.c | 7 |
6 files changed, 103 insertions, 78 deletions
diff --git a/swaynag/config.c b/swaynag/config.c index 6db7cce5..a0bf3197 100644 --- a/swaynag/config.c +++ b/swaynag/config.c @@ -11,24 +11,40 @@ #include "util.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" -static char *read_from_stdin(void) { - char *buffer = NULL; - size_t buffer_len = 0; - char *line = NULL; - size_t line_size = 0; - ssize_t nread; - while ((nread = getline(&line, &line_size, stdin)) != -1) { +static char *read_and_trim_stdin(void) { + char *buffer = NULL, *line = NULL; + size_t buffer_len = 0, line_size = 0; + while (1) { + ssize_t nread = getline(&line, &line_size, stdin); + if (nread == -1) { + if (feof(stdin)) { + break; + } else { + perror("getline"); + goto freeline; + } + } buffer = realloc(buffer, buffer_len + nread + 1); - snprintf(&buffer[buffer_len], nread + 1, "%s", line); + if (!buffer) { + perror("realloc"); + goto freebuf; + } + memcpy(&buffer[buffer_len], line, nread + 1); buffer_len += nread; } free(line); - while (buffer && buffer[buffer_len - 1] == '\n') { + while (buffer_len && buffer[buffer_len - 1] == '\n') { buffer[--buffer_len] = '\0'; } return buffer; + +freeline: + free(line); +freebuf: + free(buffer); + return NULL; } int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, @@ -150,8 +166,11 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, fprintf(stderr, "Missing action for button %s\n", optarg); return EXIT_FAILURE; } - struct swaynag_button *button; - button = calloc(sizeof(struct swaynag_button), 1); + struct swaynag_button *button = calloc(sizeof(struct swaynag_button), 1); + if (!button) { + perror("calloc"); + return EXIT_FAILURE; + } button->text = strdup(optarg); button->type = SWAYNAG_ACTION_COMMAND; button->action = strdup(argv[optind]); @@ -208,21 +227,26 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, case 'f': // Font if (type) { free(type->font); + pango_font_description_free(type->font_description); type->font = strdup(optarg); + type->font_description = pango_font_description_from_string(type->font); } break; case 'l': // Detailed Message if (swaynag) { free(swaynag->details.message); - swaynag->details.message = read_from_stdin(); + swaynag->details.message = read_and_trim_stdin(); + if (!swaynag->details.message) { + return EXIT_FAILURE; + } swaynag->details.button_up.text = strdup("▲"); swaynag->details.button_down.text = strdup("▼"); } break; case 'L': // Detailed Button Text if (swaynag) { - free(swaynag->details.button_details->text); - swaynag->details.button_details->text = strdup(optarg); + free(swaynag->details.button_details.text); + swaynag->details.button_details.text = strdup(optarg); } break; case 'm': // Message @@ -239,8 +263,7 @@ int swaynag_parse_options(int argc, char **argv, struct swaynag *swaynag, break; case 's': // Dismiss Button Text if (swaynag) { - struct swaynag_button *button_close; - button_close = swaynag->buttons->items[0]; + struct swaynag_button *button_close = swaynag->buttons->items[0]; free(button_close->text); button_close->text = strdup(optarg); } @@ -399,23 +422,24 @@ int swaynag_load_config(char *path, struct swaynag *swaynag, list_t *types) { if (line[0] == '[') { char *close = strchr(line, ']'); - if (!close) { - fprintf(stderr, "Closing bracket not found on line %d\n", - line_number); + if (!close || close != &line[nread - 2] || nread <= 3) { + fprintf(stderr, "Line %d is malformed\n", line_number); result = 1; break; } - char *name = calloc(1, close - line); - strncat(name, line + 1, close - line - 1); - type = swaynag_type_get(types, name); + *close = '\0'; + type = swaynag_type_get(types, &line[1]); if (!type) { - type = swaynag_type_new(name); + type = swaynag_type_new(&line[1]); list_add(types, type); } - free(name); } else { - char *flag = malloc(sizeof(char) * (nread + 3)); - sprintf(flag, "--%s", line); + char *flag = malloc(nread + 3); + if (!flag) { + perror("calloc"); + return EXIT_FAILURE; + } + snprintf(flag, nread + 3, "--%s", line); char *argv[] = {"swaynag", flag}; result = swaynag_parse_options(2, argv, swaynag, types, type, NULL, NULL); diff --git a/swaynag/main.c b/swaynag/main.c index 88007818..2ce37831 100644 --- a/swaynag/main.c +++ b/swaynag/main.c @@ -20,33 +20,25 @@ void sway_terminate(int code) { } int main(int argc, char **argv) { - int exit_code = EXIT_SUCCESS; + int status = EXIT_SUCCESS; list_t *types = create_list(); swaynag_types_add_default(types); - memset(&swaynag, 0, sizeof(swaynag)); swaynag.buttons = create_list(); wl_list_init(&swaynag.outputs); wl_list_init(&swaynag.seats); - struct swaynag_button *button_close = - calloc(sizeof(struct swaynag_button), 1); - button_close->text = strdup("X"); - button_close->type = SWAYNAG_ACTION_DISMISS; - list_add(swaynag.buttons, button_close); - - swaynag.details.button_details = - calloc(sizeof(struct swaynag_button), 1); - swaynag.details.button_details->text = strdup("Toggle details"); - swaynag.details.button_details->type = SWAYNAG_ACTION_EXPAND; + struct swaynag_button button_close = { 0 }; + button_close.text = strdup("X"); + button_close.type = SWAYNAG_ACTION_DISMISS; + list_add(swaynag.buttons, &button_close); char *config_path = NULL; bool debug = false; - int launch_status = swaynag_parse_options(argc, argv, NULL, NULL, NULL, + status = swaynag_parse_options(argc, argv, NULL, NULL, NULL, &config_path, &debug); - if (launch_status != 0) { - exit_code = launch_status; + if (status != 0) { goto cleanup; } sway_log_init(debug ? SWAY_DEBUG : SWAY_ERROR, NULL); @@ -56,29 +48,29 @@ int main(int argc, char **argv) { } if (config_path) { sway_log(SWAY_DEBUG, "Loading config file: %s", config_path); - int config_status = swaynag_load_config(config_path, &swaynag, types); - free(config_path); - if (config_status != 0) { - exit_code = config_status; + status = swaynag_load_config(config_path, &swaynag, types); + if (status != 0) { goto cleanup; } } + swaynag.details.button_details.text = strdup("Toggle details"); + swaynag.details.button_details.type = SWAYNAG_ACTION_EXPAND; + if (argc > 1) { struct swaynag_type *type_args = swaynag_type_new("<args>"); list_add(types, type_args); - int result = swaynag_parse_options(argc, argv, &swaynag, types, + status = swaynag_parse_options(argc, argv, &swaynag, types, type_args, NULL, NULL); - if (result != 0) { - exit_code = result; + if (status != 0) { goto cleanup; } } if (!swaynag.message) { sway_log(SWAY_ERROR, "No message passed. Please provide --message/-m"); - exit_code = EXIT_FAILURE; + status = EXIT_FAILURE; goto cleanup; } @@ -99,10 +91,7 @@ int main(int argc, char **argv) { swaynag_types_free(types); if (swaynag.details.message) { - list_add(swaynag.buttons, swaynag.details.button_details); - } else { - free(swaynag.details.button_details->text); - free(swaynag.details.button_details); + list_add(swaynag.buttons, &swaynag.details.button_details); } sway_log(SWAY_DEBUG, "Output: %s", swaynag.type->output); @@ -120,12 +109,11 @@ int main(int argc, char **argv) { swaynag_setup(&swaynag); swaynag_run(&swaynag); - return exit_code; + return status; cleanup: swaynag_types_free(types); - free(swaynag.details.button_details->text); - free(swaynag.details.button_details); + free(swaynag.details.button_details.text); swaynag_destroy(&swaynag); - return exit_code; + return status; } diff --git a/swaynag/meson.build b/swaynag/meson.build index 71f2fc2d..aef21483 100644 --- a/swaynag/meson.build +++ b/swaynag/meson.build @@ -5,13 +5,14 @@ executable( 'render.c', 'swaynag.c', 'types.c', + wl_protos_src, ], include_directories: [sway_inc], dependencies: [ cairo, - client_protos, pango, pangocairo, + rt, wayland_client, wayland_cursor, ], diff --git a/swaynag/render.c b/swaynag/render.c index d72f42c2..21b03289 100644 --- a/swaynag/render.c +++ b/swaynag/render.c @@ -9,7 +9,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) { int text_width, text_height; - get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL, + get_text_size(cairo, swaynag->type->font_description, &text_width, &text_height, NULL, 1, true, "%s", swaynag->message); int padding = swaynag->type->message_padding; @@ -22,7 +22,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) { cairo_set_source_u32(cairo, swaynag->type->text); cairo_move_to(cairo, padding, (int)(ideal_height - text_height) / 2); - render_text(cairo, swaynag->type->font, 1, false, + render_text(cairo, swaynag->type->font_description, 1, false, "%s", swaynag->message); return ideal_surface_height; @@ -31,7 +31,7 @@ static uint32_t render_message(cairo_t *cairo, struct swaynag *swaynag) { static void render_details_scroll_button(cairo_t *cairo, struct swaynag *swaynag, struct swaynag_button *button) { int text_width, text_height; - get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL, + get_text_size(cairo, swaynag->type->font_description, &text_width, &text_height, NULL, 1, true, "%s", button->text); int border = swaynag->type->button_border_thickness; @@ -50,17 +50,17 @@ static void render_details_scroll_button(cairo_t *cairo, cairo_set_source_u32(cairo, swaynag->type->button_text); cairo_move_to(cairo, button->x + border + padding, button->y + border + (button->height - text_height) / 2); - render_text(cairo, swaynag->type->font, 1, true, + render_text(cairo, swaynag->type->font_description, 1, true, "%s", button->text); } static int get_detailed_scroll_button_width(cairo_t *cairo, struct swaynag *swaynag) { int up_width, down_width, temp_height; - get_text_size(cairo, swaynag->type->font, &up_width, &temp_height, NULL, + get_text_size(cairo, swaynag->type->font_description, &up_width, &temp_height, NULL, 1, true, "%s", swaynag->details.button_up.text); - get_text_size(cairo, swaynag->type->font, &down_width, &temp_height, NULL, + get_text_size(cairo, swaynag->type->font_description, &down_width, &temp_height, NULL, 1, true, "%s", swaynag->details.button_down.text); @@ -83,7 +83,7 @@ static uint32_t render_detailed(cairo_t *cairo, struct swaynag *swaynag, swaynag->details.y = y + decor; swaynag->details.width = width - decor * 2; - PangoLayout *layout = get_pango_layout(cairo, swaynag->type->font, + PangoLayout *layout = get_pango_layout(cairo, swaynag->type->font_description, swaynag->details.message, 1, false); pango_layout_set_width(layout, (swaynag->details.width - padding * 2) * PANGO_SCALE); @@ -172,7 +172,7 @@ static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag, struct swaynag_button *button = swaynag->buttons->items[button_index]; int text_width, text_height; - get_text_size(cairo, swaynag->type->font, &text_width, &text_height, NULL, + get_text_size(cairo, swaynag->type->font_description, &text_width, &text_height, NULL, 1, true, "%s", button->text); int border = swaynag->type->button_border_thickness; @@ -201,7 +201,7 @@ static uint32_t render_button(cairo_t *cairo, struct swaynag *swaynag, cairo_set_source_u32(cairo, swaynag->type->button_text); cairo_move_to(cairo, button->x + padding, button->y + padding); - render_text(cairo, swaynag->type->font, 1, true, + render_text(cairo, swaynag->type->font_description, 1, true, "%s", button->text); *x = button->x - border; diff --git a/swaynag/swaynag.c b/swaynag/swaynag.c index 9b57d578..5620155d 100644 --- a/swaynag/swaynag.c +++ b/swaynag/swaynag.c @@ -28,8 +28,13 @@ static bool terminal_execute(char *terminal, char *command) { fprintf(tmp, "#!/bin/sh\nrm %s\n%s", fname, command); fclose(tmp); chmod(fname, S_IRUSR | S_IWUSR | S_IXUSR); - char *cmd = malloc(sizeof(char) * (strlen(terminal) + strlen(" -e ") + strlen(fname) + 1)); - sprintf(cmd, "%s -e %s", terminal, fname); + size_t cmd_size = strlen(terminal) + strlen(" -e ") + strlen(fname) + 1; + char *cmd = malloc(cmd_size); + if (!cmd) { + perror("malloc"); + return false; + } + snprintf(cmd, cmd_size, "%s -e %s", terminal, fname); execlp("sh", "sh", "-c", cmd, NULL); sway_log_errno(SWAY_ERROR, "Failed to run command, execlp() returned."); free(cmd); @@ -58,7 +63,7 @@ static void swaynag_button_execute(struct swaynag *swaynag, } else if (pid == 0) { // Child of the child. Will be reparented to the init process char *terminal = getenv("TERMINAL"); - if (button->terminal && terminal && strlen(terminal)) { + if (button->terminal && terminal && *terminal) { sway_log(SWAY_DEBUG, "Found $TERMINAL: %s", terminal); if (!terminal_execute(terminal, button->action)) { swaynag_destroy(swaynag); @@ -138,7 +143,7 @@ static void update_cursor(struct swaynag_seat *seat) { const char *cursor_theme = getenv("XCURSOR_THEME"); unsigned cursor_size = 24; const char *env_cursor_size = getenv("XCURSOR_SIZE"); - if (env_cursor_size && strlen(env_cursor_size) > 0) { + if (env_cursor_size && *env_cursor_size) { errno = 0; char *end; unsigned size = strtoul(env_cursor_size, &end, 10); @@ -339,6 +344,7 @@ static void handle_global(void *data, struct wl_registry *registry, struct swaynag_seat *seat = calloc(1, sizeof(struct swaynag_seat)); if (!seat) { + perror("calloc"); return; } @@ -356,6 +362,10 @@ static void handle_global(void *data, struct wl_registry *registry, if (!swaynag->output) { struct swaynag_output *output = calloc(1, sizeof(struct swaynag_output)); + if (!output) { + perror("calloc"); + return; + } output->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 4); output->wl_name = name; @@ -511,13 +521,8 @@ void swaynag_destroy(struct swaynag *swaynag) { swaynag_seat_destroy(seat); } - if (&swaynag->buffers[0]) { - destroy_buffer(&swaynag->buffers[0]); - } - - if (&swaynag->buffers[1]) { - destroy_buffer(&swaynag->buffers[1]); - } + destroy_buffer(&swaynag->buffers[0]); + destroy_buffer(&swaynag->buffers[1]); if (swaynag->outputs.prev || swaynag->outputs.next) { struct swaynag_output *output, *temp; diff --git a/swaynag/types.c b/swaynag/types.c index 7bef0f87..a46aacd5 100644 --- a/swaynag/types.c +++ b/swaynag/types.c @@ -33,6 +33,8 @@ struct swaynag_type *swaynag_type_new(const char *name) { void swaynag_types_add_default(list_t *types) { struct swaynag_type *type_defaults = swaynag_type_new("<defaults>"); type_defaults->font = strdup("pango:Monospace 10"); + type_defaults->font_description = + pango_font_description_from_string(type_defaults->font); type_defaults->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; @@ -94,6 +96,10 @@ void swaynag_type_merge(struct swaynag_type *dest, struct swaynag_type *src) { dest->font = strdup(src->font); } + if (src->font_description) { + dest->font_description = pango_font_description_copy(src->font_description); + } + if (src->output) { dest->output = strdup(src->output); } @@ -173,6 +179,7 @@ void swaynag_type_merge(struct swaynag_type *dest, struct swaynag_type *src) { void swaynag_type_free(struct swaynag_type *type) { free(type->name); free(type->font); + pango_font_description_free(type->font_description); free(type->output); free(type); } |