summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c78
1 files changed, 64 insertions, 14 deletions
diff --git a/main.c b/main.c
index ce8edc8..e43dbcb 100644
--- a/main.c
+++ b/main.c
@@ -41,12 +41,20 @@ struct swaybg_state {
struct zxdg_output_manager_v1 *xdg_output_manager;
struct wl_list configs; // struct swaybg_output_config::link
struct wl_list outputs; // struct swaybg_output::link
+ struct wl_list images; // struct swaybg_image::link
bool run_display;
};
+struct swaybg_image {
+ const char *path;
+ cairo_surface_t *surface;
+ struct wl_list link;
+};
+
struct swaybg_output_config {
char *output;
- cairo_surface_t *image;
+ const char *image_path;
+ struct swaybg_image *image;
enum background_mode mode;
uint32_t color;
struct wl_list link;
@@ -115,8 +123,10 @@ static void render_frame(struct swaybg_output *output) {
cairo_set_source_u32(cairo, output->config->color);
cairo_paint(cairo);
}
- render_background_image(cairo, output->config->image,
+ if (output->config->image->surface) {
+ render_background_image(cairo, output->config->image->surface,
output->config->mode, buffer_width, buffer_height);
+ }
}
wl_surface_set_buffer_scale(output->surface, output->scale);
@@ -125,6 +135,17 @@ static void render_frame(struct swaybg_output *output) {
wl_surface_commit(output->surface);
}
+static void destroy_swaybg_image(struct swaybg_image *image) {
+ if (!image) {
+ return;
+ }
+ if (image->surface) {
+ cairo_surface_destroy(image->surface);
+ }
+ wl_list_remove(&image->link);
+ free(image);
+}
+
static void destroy_swaybg_output_config(struct swaybg_output_config *config) {
if (!config) {
return;
@@ -371,10 +392,8 @@ static bool store_swaybg_output_config(struct swaybg_state *state,
wl_list_for_each(oc, &state->configs, link) {
if (strcmp(config->output, oc->output) == 0) {
// Merge on top
- if (config->image) {
- free(oc->image);
- oc->image = config->image;
- config->image = NULL;
+ if (config->image_path) {
+ oc->image_path = config->image_path;
}
if (config->color) {
oc->color = config->color;
@@ -436,11 +455,7 @@ static void parse_command_line(int argc, char **argv,
config->color = parse_color(optarg);
break;
case 'i': // image
- free(config->image);
- config->image = load_background_image(optarg);
- if (!config->image) {
- swaybg_log(LOG_ERROR, "Failed to load image: %s", optarg);
- }
+ config->image_path = optarg;
break;
case 'm': // mode
config->mode = parse_background_mode(optarg);
@@ -490,10 +505,10 @@ static void parse_command_line(int argc, char **argv,
config = NULL;
struct swaybg_output_config *tmp = NULL;
wl_list_for_each_safe(config, tmp, &state->configs, link) {
- if (!config->image && !config->color) {
+ if (!config->image_path && !config->color) {
destroy_swaybg_output_config(config);
} else if (config->mode == BACKGROUND_MODE_INVALID) {
- config->mode = config->image
+ config->mode = config->image_path
? BACKGROUND_MODE_STRETCH
: BACKGROUND_MODE_SOLID_COLOR;
}
@@ -506,9 +521,39 @@ int main(int argc, char **argv) {
struct swaybg_state state = {0};
wl_list_init(&state.configs);
wl_list_init(&state.outputs);
+ wl_list_init(&state.images);
parse_command_line(argc, argv, &state);
+ // Identify distinct image paths which will need to be loaded
+ struct swaybg_image *image;
+ struct swaybg_output_config *config;
+ wl_list_for_each(config, &state.configs, link) {
+ if (!config->image_path) {
+ continue;
+ }
+ wl_list_for_each(image, &state.images, link) {
+ if (strcmp(image->path, config->image_path) == 0) {
+ config->image = image;
+ break;
+ }
+ }
+ if (config->image) {
+ continue;
+ }
+ image = calloc(1, sizeof(struct swaybg_image));
+ image->path = config->image_path;
+ wl_list_insert(&state.images, &image->link);
+ config->image = image;
+ }
+
+ wl_list_for_each(image, &state.images, link) {
+ image->surface = load_background_image(image->path);
+ if (!image->surface) {
+ swaybg_log(LOG_ERROR, "Failed to load image: %s", image->path);
+ }
+ }
+
state.display = wl_display_connect(NULL);
if (!state.display) {
swaybg_log(LOG_ERROR, "Unable to connect to the compositor. "
@@ -555,10 +600,15 @@ int main(int argc, char **argv) {
destroy_swaybg_output(output);
}
- struct swaybg_output_config *config = NULL, *tmp_config = NULL;
+ struct swaybg_output_config *tmp_config = NULL;
wl_list_for_each_safe(config, tmp_config, &state.configs, link) {
destroy_swaybg_output_config(config);
}
+ struct swaybg_image *tmp_image;
+ wl_list_for_each_safe(image, tmp_image, &state.images, link) {
+ destroy_swaybg_image(image);
+ }
+
return 0;
}