@ -21,35 +21,59 @@
# include <unistd.h>
# include <sys/inotify.h>
# include <libgen.h>
# include <time.h>
# include "util.h"
# include "autoreload.h"
const struct timespec ten_ms = { 0 , 10000000 } ;
void arl_cleanup ( void )
CLEANUP void arl_cleanup ( arl_t * arl )
{
if ( a utoreload. fd ! = - 1 & & autoreload . wd ! = - 1 )
if ( arl - > fd ! = - 1 & & arl - > wd ! = - 1 )
{
if ( inotify_rm_watch ( a utoreload. fd , autoreload . wd ) )
if ( inotify_rm_watch ( a rl- > fd , arl - > wd ) )
error ( 0 , 0 , " Failed to remove inotify watch. " ) ;
}
}
void arl_handle ( void )
static void arl_setup_dir ( arl_t * arl , const char * filepath )
{
char * dntmp , * dn ;
if ( arl - > fd = = - 1 )
{
error ( 0 , 0 , " Uninitialized, could not add inotify watch on directory. " ) ;
return ;
}
/* get dirname */
dntmp = ( char * ) strdup ( filepath ) ;
dn = ( char * ) dirname ( dntmp ) ;
/* this is not one-shot as other stuff may be created too
note : we won ' t handle deletion of the directory itself ,
this is a design decision */
arl - > wd = inotify_add_watch ( arl - > fd , dn , IN_CREATE ) ;
if ( arl - > wd = = - 1 )
error ( 0 , 0 , " Failed to add inotify watch on directory '%s'. " , dn ) ;
else
arl - > watching_dir = true ;
free ( dntmp ) ;
}
bool arl_handle ( arl_t * arl , const char * filepath )
{
bool reload = false ;
ssize_t len ;
char buf [ 4096 ] __attribute__ ( ( aligned ( __alignof__ ( struct inotify_event ) ) ) ) ;
const struct inotify_event * event ;
char * ptr ;
char * fntmp , * fn ;
len = read ( autoreload . fd , buf , sizeof buf ) ;
len = read ( a rl- > fd , buf , sizeof buf ) ;
if ( len = = - 1 )
{
error ( 0 , 0 , " Failed to read inotify events. " ) ;
return ;
return false ;
}
for ( ptr = buf ; ptr < buf + len ;
@ -61,17 +85,16 @@ void arl_handle(void)
/* events from watching the file itself */
if ( event - > mask & IN_CLOSE_WRITE )
{
load_image ( fileidx ) ;
redraw ( ) ;
reload = true ;
}
if ( event - > mask & IN_DELETE_SELF )
arl_setup_dir ( ) ;
arl_setup_dir ( arl , filepath ) ;
/* events from watching the file's directory */
if ( event - > mask & IN_CREATE )
{
fntmp = strdup ( file s[ fileidx ] . path) ;
fntmp = strdup ( file path) ;
fn = basename ( fntmp ) ;
if ( 0 = = strcmp ( event - > name , fn ) )
@ -79,76 +102,49 @@ void arl_handle(void)
/* this is the file we're looking for */
/* cleanup, this has not been one-shot */
if ( a utoreload. watching_dir )
if ( a rl- > watching_dir )
{
if ( inotify_rm_watch ( a utoreload. fd , autoreload . wd ) )
if ( inotify_rm_watch ( a rl- > fd , arl - > wd ) )
error ( 0 , 0 , " Failed to remove inotify watch. " ) ;
a utoreload. watching_dir = false ;
a rl- > watching_dir = false ;
}
/* when too fast, imlib2 can't load the image */
nanosleep ( & ten_ms , NULL ) ;
load_image ( fileidx ) ;
redraw ( ) ;
reload = true ;
}
free ( fntmp ) ;
}
}
return reload ;
}
void arl_init ( void )
void arl_init ( arl_t * arl )
{
/* this needs to be done only once */
a utoreload. fd = inotify_init ( ) ;
a utoreload. watching_dir = false ;
if ( a utoreload. fd = = - 1 )
a rl- > fd = inotify_init ( ) ;
a rl- > watching_dir = false ;
if ( a rl- > fd = = - 1 )
error ( 0 , 0 , " Could not initialize inotify. " ) ;
}
void arl_setup ( void )
void arl_setup ( arl_t * arl , const char * filepath )
{
if ( a utoreload. fd = = - 1 )
if ( a rl- > fd = = - 1 )
{
error ( 0 , 0 , " Uninitialized, could not add inotify watch. " ) ;
return ;
}
/* may have switched from a deleted to another image */
if ( a utoreload. watching_dir )
if ( a rl- > watching_dir )
{
if ( inotify_rm_watch ( a utoreload. fd , autoreload . wd ) )
if ( inotify_rm_watch ( a rl- > fd , arl - > wd ) )
error ( 0 , 0 , " Failed to remove inotify watch. " ) ;
a utoreload. watching_dir = false ;
a rl- > watching_dir = false ;
}
a utoreload. wd = inotify_add_watch ( autoreload . fd , files [ fileidx ] . path,
a rl- > wd = inotify_add_watch ( arl - > fd , file path,
IN_ONESHOT | IN_CLOSE_WRITE | IN_DELETE_SELF ) ;
if ( a utoreload. wd = = - 1 )
error ( 0 , 0 , " Failed to add inotify watch on file '%s'. " , file s[ fileidx ] . path) ;
if ( a rl- > wd = = - 1 )
error ( 0 , 0 , " Failed to add inotify watch on file '%s'. " , file path) ;
}
void arl_setup_dir ( void )
{
char * dntmp , * dn ;
if ( autoreload . fd = = - 1 )
{
error ( 0 , 0 , " Uninitialized, could not add inotify watch on directory. " ) ;
return ;
}
/* get dirname */
dntmp = ( char * ) strdup ( files [ fileidx ] . path ) ;
dn = ( char * ) dirname ( dntmp ) ;
/* this is not one-shot as other stuff may be created too
note : we won ' t handle deletion of the directory itself ,
this is a design decision */
autoreload . wd = inotify_add_watch ( autoreload . fd , dn , IN_CREATE ) ;
if ( autoreload . wd = = - 1 )
error ( 0 , 0 , " Failed to add inotify watch on directory '%s'. " , dn ) ;
else
autoreload . watching_dir = true ;
free ( dntmp ) ;
}