summaryrefslogtreecommitdiff
path: root/swaynag
diff options
context:
space:
mode:
Diffstat (limited to 'swaynag')
-rw-r--r--swaynag/config.c76
-rw-r--r--swaynag/main.c50
-rw-r--r--swaynag/meson.build3
-rw-r--r--swaynag/render.c18
-rw-r--r--swaynag/swaynag.c27
-rw-r--r--swaynag/types.c7
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);
}