diff --git a/.github/README.md b/.github/README.md index 054ef310..a913a724 100644 --- a/.github/README.md +++ b/.github/README.md @@ -21,6 +21,8 @@ version and further details on sxiv, how to install it and how it works. ### Changelog: +2021-09-07 - Added the fifo patch + 2021-06-11 - Added the alpha patch 2021-06-10 - Added the "allow escape key in external key handler" patch (for the lack of a better @@ -62,6 +64,9 @@ version and further details on sxiv, how to install it and how it works. - [ewmh-wm-client-machine](https://github.com/muennich/sxiv/pull/403) - sets the WM_CLIENT_MACHINE X property + - [fifo](https://github.com/muennich/sxiv/pull/369) + - adds support for pipe-based redirection for sxiv + - [image-mode-cycle](https://github.com/i-tsvetkov/sxiv-patches) - adds the ability to cycle when viewing multiple images diff --git a/Makefile b/Makefile index a9e7366b..cbdc9854 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,10 @@ HAVE_LIBEXIF = 1 #xrender = -lXrender # Uncomment to enable SVG support / SVG_IMAGE_SUPPORT_PATCH -#svglibs = `pkg-config --cflags --libs librsvg-2.0 cairo` +svglibs = `pkg-config --cflags --libs librsvg-2.0 cairo` # Uncomment to enable WebP support / WEBP_IMAGE_SUPPORT_PATCH -#webplibs = -lwebpdemux -lwebp +webplibs = -lwebpdemux -lwebp # Uncomment to enable libcurl support / LIBCURL_PATCH #curllibs = -lcurl diff --git a/image.c b/image.c index f2996fe3..b49b4cb0 100644 --- a/image.c +++ b/image.c @@ -575,7 +575,11 @@ Imlib_Image img_open(const fileinfo_t *file) stat(file->path, &st) == 0 && S_ISREG(st.st_mode)) { #if WEBP_IMAGE_SUPPORT_PATCH + #if FIFO_PATCH + if (im == NULL && !strstr(file->name, "/proc/") && strcmp(file->name, "/dev/stdin")) + #else if (im == NULL) + #endif // FIFO_PATCH im = load_webp_firstframe_im(file); #endif // WEBP_IMAGE_SUPPORT_PATCH diff --git a/main.c b/main.c index f0c84bab..bd870547 100644 --- a/main.c +++ b/main.c @@ -67,10 +67,10 @@ int filecnt, fileidx; int alternate; int markcnt; int markidx; -#if LIBCURL_PATCH +#if LIBCURL_PATCH || FIFO_PATCH char **rmfiles; int rmcnt, rmidx; -#endif // LIBCURL_PATCH +#endif // LIBCURL_PATCH | FIFO_PATCH int prefix; bool extprefix; @@ -115,9 +115,9 @@ CLEANUP void tmp_unlink(char **rmfiles, int n) { void cleanup(void) { - #if LIBCURL_PATCH + #if LIBCURL_PATCH || FIFO_PATCH tmp_unlink(rmfiles, rmidx); - #endif // LIBCURL_PATCH + #endif // LIBCURL_PATCH | FIFO_PATCH img_close(&img, false); arl_cleanup(&arl); tns_free(&tns); @@ -130,11 +130,35 @@ void internal_check_add_file(char *filename, char *url, bool given) void check_add_file(char *filename, bool given) #endif // LIBCURL_PATCH { - char *path; + char *path = NULL; + #if FIFO_PATCH + struct stat st; + bool rm = false; + #endif // FIFO_PATCH if (*filename == '\0') return; + #if FIFO_PATCH + if (access(filename, R_OK) == 0 && stat(filename, &st) == 0) { + switch (st.st_mode & S_IFMT) { + case S_IFREG: + path = realpath(filename, NULL); + break; + + case S_IFIFO: + path = tmp_pipe_drain(filename); + rm = true; + break; + } + } + + if (path == NULL) { + if (given) + error(0, errno, "%s", filename); + return; + } + #else if (access(filename, R_OK) < 0 || (path = realpath(filename, NULL)) == NULL) { @@ -142,6 +166,7 @@ void check_add_file(char *filename, bool given) error(0, errno, "%s", filename); return; } + #endif // FIFO_PATCH if (fileidx == filecnt) { filecnt *= 2; @@ -166,6 +191,18 @@ void check_add_file(char *filename, bool given) if (given) files[fileidx].flags |= FF_WARN; fileidx++; + + #if FIFO_PATCH + if (rm) { + if (rmidx == rmcnt) { + rmcnt *= 2; + rmfiles = erealloc(rmfiles, rmcnt * sizeof(char*)); + memset(&rmfiles[rmcnt/2], 0, rmcnt/2 * sizeof(char*)); + } + + rmfiles[rmidx++] = path; + } + #endif // FIFO_PATCH } #if LIBCURL_PATCH @@ -961,11 +998,12 @@ int main(int argc, char **argv) files = emalloc(filecnt * sizeof(*files)); memset(files, 0, filecnt * sizeof(*files)); fileidx = 0; - #if LIBCURL_PATCH + + #if LIBCURL_PATCH || FIFO_PATCH rmcnt = 16; rmfiles = emalloc(rmcnt * sizeof(char*)); rmidx = 0; - #endif // LIBCURL_PATCH + #endif // LIBCURL_PATCH | FIFO_PATCH if (options->from_stdin) { n = 0; diff --git a/patches.def.h b/patches.def.h index c960eced..f9b86895 100644 --- a/patches.def.h +++ b/patches.def.h @@ -62,6 +62,20 @@ */ #define EWMH_WM_CLIENT_MACHINE 0 +/* Adds support for pipe-based redirection for sxiv. + * + * Example commands: + * $ sxiv <(curl -s https://i.imgur.com/JdfIbt4g.png) <(curl -s https://i.imgur.com/WwcW92d.png) + * $ curl -s https://i.imgur.com/JdfIbt4g.png | sxiv /dev/stdin + * + * This is not possible out of the box because FIFO/pipe files are not seekable which breaks + * things. The patch works around this by draining the pipe to a temporary file which is displayed + * and unlinked on exit. + * + * https://github.com/muennich/sxiv/pull/369 + */ +#define FIFO_PATCH 0 + /* Adds the ability to cycle when viewing multiple images. * https://github.com/i-tsvetkov/sxiv-patches */ diff --git a/sxiv.h b/sxiv.h index e940753e..be6a6142 100644 --- a/sxiv.h +++ b/sxiv.h @@ -411,6 +411,10 @@ int r_opendir(r_dir_t*, const char*, bool); int r_closedir(r_dir_t*); char* r_readdir(r_dir_t*, bool); int r_mkdir(char*); +#if FIFO_PATCH +char* tmp_pipe_drain(char*); +CLEANUP void tmp_unlink(char**, int); +#endif // FIFO_PATCH /* window.c */ diff --git a/util.c b/util.c index b956fd71..b8b3306c 100644 --- a/util.c +++ b/util.c @@ -211,3 +211,37 @@ int r_mkdir(char *path) return 0; } +#if FIFO_PATCH +char *tmp_pipe_drain(char *pipe) +{ + int n; + char buf[1024]; + char *path = emalloc(PATH_MAX); + int fd; + + snprintf(path, PATH_MAX, "/tmp/sxiv-XXXXXX"); + if ((fd = mkstemp(path)) < 0) { + free(path); + return NULL; + } + + FILE *src = fopen(pipe, "rb"); + FILE *dst = fdopen(fd, "wb"); + + while ((n = fread(buf, sizeof(char), sizeof(buf), src)) > 0) { + if (fwrite(buf, sizeof(char), n, dst) < n) { + free(path); + return NULL; + } + } + + fclose(dst); + fclose(src); + return path; +} + +CLEANUP void tmp_unlink(char **rmfiles, int n) { + while (n--) + unlink(rmfiles[n]); +} +#endif // FIFO_PATCH \ No newline at end of file