diff options
| -rw-r--r-- | config.mk | 7 | ||||
| -rw-r--r-- | man/Makefile | 1 | ||||
| -rw-r--r-- | man/feh.pre | 8 | ||||
| -rw-r--r-- | src/feh.h | 3 | ||||
| -rw-r--r-- | src/filelist.c | 2 | ||||
| -rw-r--r-- | src/help.raw | 1 | ||||
| -rw-r--r-- | src/main.c | 34 | ||||
| -rw-r--r-- | src/options.c | 12 | ||||
| -rw-r--r-- | src/options.h | 4 | ||||
| -rw-r--r-- | src/winwidget.c | 67 | ||||
| -rw-r--r-- | src/winwidget.h | 4 | 
11 files changed, 140 insertions, 3 deletions
| @@ -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, @@ -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 @@ -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); | 
