diff --git a/include/buffer.h b/include/buffer.h index eb807c2..f60cfc4 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -19,6 +19,9 @@ void screencopy_frame_handle_ready(void *data, uint32_t tv_nsec); void screencopy_frame_handle_failed(void *data, struct zwlr_screencopy_frame_v1 *frame); -bool buffer_init_from_screencopy(struct swappy_state *state); void screencopy_destroy_buffer(struct swappy_buffer *buffer); + +bool buffer_init_from_screencopy(struct swappy_state *state); +bool buffer_init_from_file(struct swappy_state *state); + bool buffer_parse_geometry(struct swappy_state *state); diff --git a/include/swappy.h b/include/swappy.h index fa2de24..3ad0cd9 100644 --- a/include/swappy.h +++ b/include/swappy.h @@ -106,6 +106,7 @@ struct swappy_state { struct swappy_state_ui *ui; cairo_surface_t *cairo_surface; + cairo_surface_t *image_surface; struct wl_display *display; struct wl_registry *registry; diff --git a/src/application.c b/src/application.c index 073fc8e..4de1a86 100644 --- a/src/application.c +++ b/src/application.c @@ -155,6 +155,7 @@ void arrow_clicked_handler(GtkWidget *widget, struct swappy_state *state) { void application_finish(struct swappy_state *state) { paint_free_all(state); cairo_surface_destroy(state->cairo_surface); + cairo_surface_destroy(state->image_surface); g_free(state->storage_path); g_free(state->geometry_str); g_free(state->geometry); @@ -541,6 +542,8 @@ static gboolean is_file_valid(const char *file) { return false; } + cairo_surface_destroy(surface); + return true; } @@ -561,6 +564,10 @@ static gint command_line_handler(GtkApplication *app, if (!is_file_valid(state->file_str)) { return EXIT_FAILURE; } + + if (!buffer_init_from_file(state)) { + return EXIT_FAILURE; + } } if (!init_gtk_window(state)) { diff --git a/src/buffer.c b/src/buffer.c index b7fce67..3904a6d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -174,6 +174,29 @@ bool buffer_init_from_screencopy(struct swappy_state *state) { return true; } +bool buffer_init_from_file(struct swappy_state *state) { + char *file = state->file_str; + + cairo_surface_t *surface = cairo_image_surface_create_from_png(file); + + g_assert(surface); + + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + + struct swappy_box *geometry = g_new(struct swappy_box, 1); + + geometry->x = 0; + geometry->y = 0; + geometry->width = (int32_t)width; + geometry->height = (int32_t)height; + + state->geometry = geometry; + state->image_surface = surface; + + return true; +} + bool buffer_parse_geometry(struct swappy_state *state) { struct swappy_box *geometry = g_new(struct swappy_box, 1); char *geometry_str = state->geometry_str; diff --git a/src/render.c b/src/render.c index fd3f404..761c250 100644 --- a/src/render.c +++ b/src/render.c @@ -209,6 +209,18 @@ static void render_buffer(cairo_t *cr, struct swappy_state *state) { } } +static void render_image(cairo_t *cr, struct swappy_state *state) { + if (!state->image_surface) { + return; + } + + cairo_pattern_t *output_pattern = + cairo_pattern_create_for_surface(state->image_surface); + cairo_set_source(cr, output_pattern); + cairo_pattern_destroy(output_pattern); + cairo_paint(cr); +} + static void render_background(cairo_t *cr) { cairo_set_source_rgb(cr, 0, 0, 0); cairo_paint(cr); @@ -270,6 +282,7 @@ void render_state(struct swappy_state *state) { render_background(cr); render_buffer(cr, state); + render_image(cr, state); render_paints(cr, state); // Drawing is finished, notify the GtkDrawingArea it needs to be redrawn.