aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--src/imv.c65
-rw-r--r--src/imv.h4
-rw-r--r--src/main.c7
4 files changed, 63 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index b2ceb04..6a05aa8 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ CONFIGPREFIX ?= /etc
CFLAGS ?= -W -Wall -pedantic -Wmissing-prototypes
CFLAGS += -std=c99
CPPFLAGS += $(shell sdl2-config --cflags) -D_XOPEN_SOURCE=700
-LIBS := $(shell sdl2-config --libs) -lfreeimage -lSDL2_ttf -lfontconfig -lpthread
+LIBS := $(shell sdl2-config --libs) -lfreeimage -lpng -lSDL2_ttf -lfontconfig -lpthread
BUILDDIR ?= build
TARGET := $(BUILDDIR)/imv
diff --git a/src/imv.c b/src/imv.c
index c75a243..b138eaf 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -18,7 +18,6 @@
#include "list.h"
#include "source.h"
#include "backend.h"
-#include "backend_freeimage.h"
#include "image.h"
#include "navigator.h"
#include "viewport.h"
@@ -54,6 +53,11 @@ enum background_type {
BACKGROUND_TYPE_COUNT
};
+struct backend_chain {
+ struct imv_backend *backend;
+ struct backend_chain *next;
+};
+
struct imv {
bool quit;
bool loading;
@@ -80,7 +84,7 @@ struct imv {
char *font_name;
struct imv_binds *binds;
struct imv_navigator *navigator;
- struct imv_backend *backend;
+ struct backend_chain *backends;
struct imv_source *source;
struct imv_source *last_source;
struct imv_commands *commands;
@@ -284,7 +288,8 @@ struct imv *imv_create(void)
imv->font_name = strdup("Monospace:24");
imv->binds = imv_binds_create();
imv->navigator = imv_navigator_create();
- imv->backend = imv_backend_freeimage();
+
+ imv->backends = NULL;
imv->source = NULL;
imv->last_source = NULL;
imv->commands = imv_commands_create();
@@ -367,7 +372,14 @@ void imv_free(struct imv *imv)
free(imv->overlay_text);
imv_binds_free(imv->binds);
imv_navigator_free(imv->navigator);
- imv->backend->free(imv->backend);
+
+ struct backend_chain *chain = imv->backends;
+ while (chain) {
+ struct backend_chain *next_backend = chain->next;
+ chain->backend->free(chain->backend);
+ chain = next_backend;
+ }
+
if (imv->source) {
imv->source->free(imv->source);
}
@@ -404,6 +416,14 @@ void imv_free(struct imv *imv)
free(imv);
}
+void imv_install_backend(struct imv *imv, struct imv_backend *backend)
+{
+ struct backend_chain *chain = malloc(sizeof(struct backend_chain));
+ chain->backend = backend;
+ chain->next = imv->backends;
+ imv->backends = chain;
+}
+
static bool parse_bg(struct imv *imv, const char *bg)
{
if(strcmp("checks", bg) == 0) {
@@ -680,7 +700,23 @@ int imv_run(struct imv *imv)
/* check we got a path back */
if(strcmp("", current_path)) {
struct imv_source *new_source;
- enum backend_result result = imv->backend->open_path(current_path, &new_source);
+
+ enum backend_result result = BACKEND_UNSUPPORTED;
+
+ if (!imv->backends) {
+ fprintf(stderr, "No backends installed. Unable to load image.\n");
+ }
+ for (struct backend_chain *chain = imv->backends; chain; chain = chain->next) {
+ struct imv_backend *backend = chain->backend;
+ result = backend->open_path(current_path, &new_source);
+ if (result == BACKEND_UNSUPPORTED) {
+ /* Try the next backend */
+ continue;
+ } else {
+ break;
+ }
+ }
+
if (result == BACKEND_SUCCESS) {
if (imv->source) {
imv->source->free(imv->source);
@@ -689,6 +725,13 @@ int imv_run(struct imv *imv)
imv->source->callback = &source_callback;
imv->source->user_data = imv;
imv->source->load_first_frame(imv->source);
+
+ imv->loading = true;
+ imv_viewport_set_playing(imv->view, true);
+
+ char title[1024];
+ generate_env_text(imv, title, sizeof title, imv->title_text);
+ imv_viewport_set_title(imv->view, title);
} else {
/* Error loading path so remove it from the navigator */
imv_navigator_remove(imv->navigator, current_path);
@@ -698,12 +741,6 @@ int imv_run(struct imv *imv)
/* imv_loader_load(imv->loader, current_path, */
/* imv->stdin_image_data, imv->stdin_image_data_len); */
- imv->loading = true;
- imv_viewport_set_playing(imv->view, true);
-
- char title[1024];
- generate_env_text(imv, title, sizeof title, imv->title_text);
- imv_viewport_set_title(imv->view, title);
}
}
@@ -738,7 +775,7 @@ int imv_run(struct imv *imv)
imv->need_redraw = true;
/* Trigger loading of a new frame, now this one's being displayed */
- if (imv->source) {
+ if (imv->source && imv->source->load_next_frame) {
imv->source->load_next_frame(imv->source);
}
}
@@ -872,7 +909,7 @@ static void handle_new_image(struct imv *imv, struct imv_bitmap *bitmap, int fra
imv->next_frame_duration = 0;
/* If this is an animated image, we should kick off loading the next frame */
- if (imv->source && frametime) {
+ if (imv->source && imv->source->load_next_frame && frametime) {
imv->source->load_next_frame(imv->source);
}
}
@@ -1393,7 +1430,7 @@ void command_next_frame(struct list *args, const char *argstr, void *data)
(void)args;
(void)argstr;
struct imv *imv = data;
- if (imv->source) {
+ if (imv->source && imv->source->load_next_frame) {
imv->source->load_next_frame(imv->source);
imv->next_frame_due = 1; /* Earliest possible non-zero timestamp */
}
diff --git a/src/imv.h b/src/imv.h
index 8840776..594ce33 100644
--- a/src/imv.h
+++ b/src/imv.h
@@ -4,10 +4,14 @@
#include <stdbool.h>
struct imv;
+struct imv_backend;
struct imv *imv_create(void);
void imv_free(struct imv *imv);
+/* Used in reverse addition order. Most recently added is the first used. */
+void imv_install_backend(struct imv *imv, struct imv_backend *backend);
+
bool imv_load_config(struct imv *imv);
bool imv_parse_args(struct imv *imv, int argc, char **argv);
diff --git a/src/main.c b/src/main.c
index d38520d..3f96b02 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,9 @@
#include "imv.h"
+#include "backend.h"
+#include "backend_freeimage.h"
+#include "backend_libpng.h"
+
int main(int argc, char** argv)
{
struct imv *imv = imv_create();
@@ -8,6 +12,9 @@ int main(int argc, char** argv)
return 1;
}
+ imv_install_backend(imv, imv_backend_freeimage());
+ imv_install_backend(imv, imv_backend_libpng());
+
if(!imv_load_config(imv)) {
imv_free(imv);
return 1;