summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.mk7
-rw-r--r--man/Makefile1
-rw-r--r--man/feh.pre8
-rw-r--r--src/feh.h3
-rw-r--r--src/filelist.c2
-rw-r--r--src/help.raw1
-rw-r--r--src/main.c34
-rw-r--r--src/options.c12
-rw-r--r--src/options.h4
-rw-r--r--src/winwidget.c67
-rw-r--r--src/winwidget.h4
11 files changed, 140 insertions, 3 deletions
diff --git a/config.mk b/config.mk
index 93bb1c3..c133e46 100644
--- a/config.mk
+++ b/config.mk
@@ -73,6 +73,13 @@ else
MAN_EXIF = disabled
endif
+ifeq (${inotify},1)
+ CFLAGS += -DHAVE_INOTIFY
+ MAN_INOTIFY = enabled
+else
+ MAN_INOTIFY = disabled
+endif
+
MAN_DATE ?= ${shell date '+%B %d, %Y'}
# Uncomment this to use dmalloc
diff --git a/man/Makefile b/man/Makefile
index 65f2bc2..3be07e3 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -12,6 +12,7 @@ all: ${TARGETS}
-e 's/\$$MAN_CURL\$$/${MAN_CURL}/' \
-e 's/\$$MAN_DEBUG\$$/${MAN_DEBUG}/' \
-e 's/\$$MAN_EXIF\$$/${MAN_EXIF}/' \
+ -e 's/\$$MAN_INOTIFY\$$/${MAN_INOTIFY}/' \
-e 's/\$$MAN_XINERAMA\$$/${MAN_XINERAMA}/' \
< ${@:.1=.pre} > $@
diff --git a/man/feh.pre b/man/feh.pre
index 4a8b0f8..19d6d6d 100644
--- a/man/feh.pre
+++ b/man/feh.pre
@@ -25,7 +25,8 @@ $VERSION$
.Pp
.
Compile-time switches: libcurl support $MAN_CURL$, Xinerama support
-$MAN_XINERAMA$, builtin EXIF support $MAN_EXIF$$MAN_DEBUG$
+$MAN_XINERAMA$, builtin EXIF support $MAN_EXIF$, inotify support
+$MAN_INOTIFY$$MAN_DEBUG$
.
.
.Sh DESCRIPTION
@@ -396,6 +397,11 @@ is set to
the output will not be displayed by default, but has to be enabled by the
toggle_info key.
.
+.It Cm --inotify
+.
+.Pq only if compiled with inotify=1
+automatically reload shown image if file was changed
+.
.It Cm -k , --keep-http
.
When viewing files using HTTP,
diff --git a/src/feh.h b/src/feh.h
index 4572652..9778efb 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -173,6 +173,9 @@ void feh_edit_inplace_lossless(winwidget w, int orientation);
gib_list *feh_wrap_string(char *text, int wrap_width, Imlib_Font fn, gib_style * style);
char *build_caption_filename(feh_file * file, short create_dir);
gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num);
+#ifdef HAVE_INOTIFY
+void feh_event_handle_inotify(void);
+#endif
/* Imlib stuff */
extern Display *disp;
diff --git a/src/filelist.c b/src/filelist.c
index b569b8a..162fd57 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -75,7 +75,7 @@ void feh_file_free(feh_file * file)
#ifdef HAVE_LIBEXIF
if (file->ed)
exif_data_unref(file->ed);
-#endif
+#endif
free(file);
return;
}
diff --git a/src/help.raw b/src/help.raw
index 067e35f..339e1f3 100644
--- a/src/help.raw
+++ b/src/help.raw
@@ -94,6 +94,7 @@ OPTIONS
--min-dimension WxH Only show images with width >= W and height >= H
--max-dimension WxH Only show images with width <= W and height <= H
--scroll-step COUNT scroll COUNT pixels when movement key is pressed
+ --inotify automatically reload shown image if file was changed
MONTAGE MODE OPTIONS
-X, --ignore-aspect Set thumbnail to specified width/height without
diff --git a/src/main.c b/src/main.c
index 57b7a7b..e8c30e2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -34,6 +34,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "wallpaper.h"
#include <termios.h>
+#ifdef HAVE_INOTIFY
+#include <sys/inotify.h>
+#endif
+
char **cmdargv = NULL;
int cmdargc = 0;
char *mode = NULL;
@@ -54,6 +58,15 @@ int main(int argc, char **argv)
init_x_and_imlib();
init_keyevents();
init_buttonbindings();
+#ifdef HAVE_INOTIFY
+ if (opt.inotify) {
+ opt.inotify_fd = inotify_init();
+ if (opt.inotify_fd < 0) {
+ opt.inotify = 0;
+ eprintf("inotify_init failed");
+ }
+ }
+#endif
}
feh_event_init();
@@ -148,6 +161,13 @@ int feh_main_iteration(int block)
FD_SET(xfd, &fdset);
if (control_via_stdin)
FD_SET(STDIN_FILENO, &fdset);
+#ifdef HAVE_INOTIFY
+ if (opt.inotify) {
+ FD_SET(opt.inotify_fd, &fdset);
+ if (opt.inotify_fd >= fdsize)
+ fdsize = opt.inotify_fd + 1;
+ }
+#endif
/* Timers */
ft = first_timer;
@@ -193,6 +213,10 @@ int feh_main_iteration(int block)
}
else if (count && (FD_ISSET(0, &fdset)))
feh_event_handle_stdin();
+#ifdef HAVE_INOTIFY
+ else if (count && (FD_ISSET(opt.inotify_fd, &fdset)))
+ feh_event_handle_inotify();
+#endif
}
} else {
/* Don't block if there are events in the queue. That's a bit rude ;-) */
@@ -206,6 +230,10 @@ int feh_main_iteration(int block)
eprintf("Connection to X display lost");
else if (count && (FD_ISSET(0, &fdset)))
feh_event_handle_stdin();
+#ifdef HAVE_INOTIFY
+ else if (count && (FD_ISSET(opt.inotify_fd, &fdset)))
+ feh_event_handle_inotify();
+#endif
}
}
if (window_num == 0)
@@ -221,6 +249,12 @@ void feh_clean_exit(void)
free(opt.menu_bg);
free(opt.menu_font);
+#ifdef HAVE_INOTIFY
+ if (opt.inotify)
+ if (close(opt.inotify_fd))
+ eprintf("inotify close failed");
+#endif
+
if(disp)
XCloseDisplay(disp);
diff --git a/src/options.c b/src/options.c
index 56323a8..d06a4e7 100644
--- a/src/options.c
+++ b/src/options.c
@@ -409,6 +409,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
{"xinerama-index", 1, 0, 239},
{"insecure" , 0, 0, 240},
{"no-recursive" , 0, 0, 241},
+#ifdef HAVE_INOTIFY
+ {"inotify" , 0, 0, 243},
+#endif
{0, 0, 0, 0}
};
int optch = 0, cmdx = 0;
@@ -735,6 +738,11 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.auto_rotate = 1;
break;
#endif
+#ifdef HAVE_INOTIFY
+ case 243:
+ opt.inotify = 1;
+ break;
+#endif
case 224:
opt.cycle_once = 1;
break;
@@ -852,6 +860,10 @@ static void show_version(void)
"exif "
#endif
+#ifdef HAVE_INOTIFY
+ "inotify "
+#endif
+
#ifdef INCLUDE_HELP
"help "
#endif
diff --git a/src/options.h b/src/options.h
index 5a5ce84..19ff55c 100644
--- a/src/options.h
+++ b/src/options.h
@@ -53,6 +53,10 @@ struct __fehoptions {
unsigned char draw_exif;
unsigned char auto_rotate;
#endif
+#ifdef HAVE_INOTIFY
+ unsigned char inotify;
+ int inotify_fd;
+#endif
unsigned char list;
unsigned char quiet;
unsigned char preload;
diff --git a/src/winwidget.c b/src/winwidget.c
index 6f64844..1a0bc7d 100644
--- a/src/winwidget.c
+++ b/src/winwidget.c
@@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "options.h"
#include "events.h"
+#ifdef HAVE_INOTIFY
+#include <sys/inotify.h>
+#endif
+
static void winwidget_unregister(winwidget win);
static void winwidget_register(winwidget win);
static winwidget winwidget_allocate(void);
@@ -78,6 +82,10 @@ static winwidget winwidget_allocate(void)
ret->click_offset_y = 0;
ret->has_rotated = 0;
+#ifdef HAVE_INOTIFY
+ ret->inotify_wd = -1;
+#endif
+
return(ret);
}
@@ -755,6 +763,14 @@ void winwidget_destroy_xwin(winwidget winwid)
void winwidget_destroy(winwidget winwid)
{
+#ifdef HAVE_INOTIFY
+ if (winwid->inotify_wd >= 0) {
+ D(("Removing inotify watch\n"));
+ if (inotify_rm_watch(opt.inotify_fd, winwid->inotify_wd))
+ eprintf("inotify_rm_watch failed");
+ winwid->inotify_wd = -1;
+ }
+#endif
winwidget_destroy_xwin(winwid);
if (winwid->name)
free(winwid->name);
@@ -768,6 +784,34 @@ void winwidget_destroy(winwidget winwid)
return;
}
+#ifdef HAVE_INOTIFY
+#define INOTIFY_BUFFER_LEN (1024 * (sizeof (struct inotify_event)) + 16)
+void feh_event_handle_inotify(void)
+{
+ D(("Received inotify events\n"));
+ char buf[INOTIFY_BUFFER_LEN];
+ int i = 0;
+ int len = read (opt.inotify_fd, buf, INOTIFY_BUFFER_LEN);
+ if (len < 0) {
+ if (errno != EINTR)
+ eprintf("inotify event read failed");
+ } else if (!len)
+ eprintf("inotify event read failed");
+ while (i < len) {
+ struct inotify_event *event;
+ event = (struct inotify_event *) &buf[i];
+ for (int i = 0; i < window_num; i++) {
+ if(windows[i]->inotify_wd == event->wd) {
+ windows[i]->inotify_wd = -1;
+ feh_reload_image(windows[i], 0, 1);
+ break;
+ }
+ }
+ i += sizeof(struct inotify_event) + event->len;
+ }
+}
+#endif
+
void winwidget_destroy_all(void)
{
int i;
@@ -801,7 +845,28 @@ winwidget winwidget_get_first_window_of_type(unsigned int type)
int winwidget_loadimage(winwidget winwid, feh_file * file)
{
D(("filename %s\n", file->filename));
- return(feh_load_image(&(winwid->im), file));
+#ifdef HAVE_INOTIFY
+ if (winwid->inotify_wd >= 0) {
+ D(("Removing inotify watch\n"));
+ if (inotify_rm_watch(opt.inotify_fd, winwid->inotify_wd))
+ eprintf("inotify_rm_watch failed");
+ winwid->inotify_wd = -1;
+ }
+#endif
+ int res = feh_load_image(&(winwid->im), file);
+#ifdef HAVE_INOTIFY
+ if (res) {
+ if (opt.inotify) {
+ D(("Adding inotify watch for %s\n", file->filename));
+ winwid->inotify_wd = inotify_add_watch(opt.inotify_fd,
+ file->filename,
+ IN_CLOSE_WRITE);
+ if (winwid->inotify_wd < 0)
+ eprintf("inotify_add_watch failed");
+ }
+ }
+#endif
+ return(res);
}
void winwidget_show(winwidget winwid)
diff --git a/src/winwidget.h b/src/winwidget.h
index 6a794e7..0555201 100644
--- a/src/winwidget.h
+++ b/src/winwidget.h
@@ -116,6 +116,10 @@ struct __winwidget {
time_t click_start_time;
unsigned char has_rotated;
+
+#ifdef HAVE_INOTIFY
+ int inotify_wd;
+#endif
};
int winwidget_loadimage(winwidget winwid, feh_file * filename);