diff options
author | Sven Willner <sven.willner@gmail.com> | 2017-08-24 20:28:24 +0200 |
---|---|---|
committer | Sven Willner <sven.willner@gmail.com> | 2017-08-24 20:28:24 +0200 |
commit | 2a981df18167cf8dd0a1310b03061010c8ef71dd (patch) | |
tree | 497849fe61e54db9f8fd028c654c7ef1cb50b22b /src | |
parent | 3b53d965289346b73a6af42225175768e5e202fc (diff) |
added inotify support
Diffstat (limited to 'src')
-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 |
8 files changed, 125 insertions, 2 deletions
@@ -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); |