diff options
Diffstat (limited to 'src/winwidget.c')
| -rw-r--r-- | src/winwidget.c | 83 | 
1 files changed, 82 insertions, 1 deletions
| diff --git a/src/winwidget.c b/src/winwidget.c index bb4fdae..fa6ac72 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);  } @@ -662,6 +670,9 @@ void winwidget_destroy_xwin(winwidget winwid)  void winwidget_destroy(winwidget winwid)  { +#ifdef HAVE_INOTIFY +    winwidget_inotify_remove(winwid); +#endif  	winwidget_destroy_xwin(winwid);  	if (winwid->name)  		free(winwid->name); @@ -673,6 +684,67 @@ void winwidget_destroy(winwidget winwid)  	return;  } +#ifdef HAVE_INOTIFY +void winwidget_inotify_remove(winwidget winwid) +{ +    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 + +#ifdef HAVE_INOTIFY +void winwidget_inotify_add(winwidget winwid, feh_file * file) +{ +    if (opt.auto_reload) { +        D(("Adding inotify watch for %s\n", file->filename)); +        char dir[PATH_MAX]; +        feh_file_dirname(dir, file, PATH_MAX); +        winwid->inotify_wd = inotify_add_watch(opt.inotify_fd, dir, IN_CLOSE_WRITE | IN_MOVED_TO); +        if (winwid->inotify_wd < 0) +            eprintf("inotify_add_watch failed"); +    } +} +#endif + +#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 j = 0; j < window_num; j++) { +            if(windows[j]->inotify_wd == event->wd) { +                if (event->mask & IN_IGNORED) { +                    D(("inotify watch was implicitely removed\n")); +                    windows[j]->inotify_wd = -1; +                } else if (event->mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) { +                    if (strcmp(event->name, FEH_FILE(windows[j]->file->data)->name) == 0) { +                        D(("inotify says file changed\n")); +                        feh_reload_image(windows[j], 0, 0); +                    } +                } +                break; +            } +        } +        i += sizeof(struct inotify_event) + event->len; +    } +} +#endif +  void winwidget_destroy_all(void)  {  	int i; @@ -706,7 +778,16 @@ 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 +    winwidget_inotify_remove(winwid); +#endif +    int res = feh_load_image(&(winwid->im), file); +#ifdef HAVE_INOTIFY +    if (res) { +        winwidget_inotify_add(winwid, file); +    } +#endif +	return(res);  }  void winwidget_show(winwidget winwid) | 
