@ -10,6 +10,7 @@
# include <sys/select.h>
# include <time.h>
# include <unistd.h>
# include <X11/Xlib.h>
/* Defines */
# define MAXSLOTS 20
@ -26,11 +27,35 @@ enum {
SwipeURDL ,
SwipeULDR
} ;
typedef int Swipe ;
enum {
EdgeAny ,
EdgeNone ,
EdgeLeft ,
EdgeRight ,
EdgeTop ,
EdgeBottom ,
CornerTopLeft ,
CornerTopRight ,
CornerBottomLeft ,
CornerBottomRight ,
} ;
typedef int Edge ;
enum {
DistanceAny ,
DistanceShort ,
DistanceMedium ,
DistanceLong ,
} ;
typedef int Distance ;
typedef struct {
int nfswipe ;
Swipe swipe ;
Edge edge ;
Distance distance ;
char * command ;
} Gesture ;
@ -41,9 +66,14 @@ typedef struct {
Gesture * gestsarr ;
int gestsarrlen ;
Swipe pendingswipe ;
Edge pendingedge ;
Distance pendingdistance ;
double xstart [ MAXSLOTS ] , xend [ MAXSLOTS ] , ystart [ MAXSLOTS ] , yend [ MAXSLOTS ] ;
unsigned nfdown = 0 , nfpendingswipe = 0 ;
struct timespec timedown ;
static Display * dpy ;
static int screen ;
static int screenwidth , screenheight ;
void
die ( char * msg )
@ -91,31 +121,119 @@ gesturecalculateswipe(double x0, double y0, double x1, double y1) {
return - 1 ;
}
Distance
gesturecalculatedistance ( double x0 , double y0 , double x1 , double y1 , Swipe swipe ) {
double dist = sqrt ( pow ( x1 - x0 , 2 ) + pow ( y1 - y0 , 2 ) ) ;
double diag = sqrt ( pow ( screenwidth , 2 ) + pow ( screenheight , 2 ) ) ;
switch ( swipe ) {
case SwipeDU :
case SwipeUD :
if ( dist > = screenheight * 0.66 ) {
return DistanceLong ;
} else if ( dist > = screenheight * 0.33 ) {
return DistanceMedium ;
} else {
return DistanceShort ;
}
break ;
case SwipeLR :
case SwipeRL :
if ( dist > = screenwidth * 0.66 ) {
return DistanceLong ;
} else if ( dist > = screenwidth * 0.33 ) {
return DistanceMedium ;
} else {
return DistanceShort ;
}
break ;
case SwipeULDR :
case SwipeDRUL :
case SwipeDLUR :
case SwipeURDL :
if ( dist > = diag * 0.66 ) {
return DistanceLong ;
} else if ( dist > = diag * 0.33 ) {
return DistanceMedium ;
} else {
return DistanceShort ;
}
break ;
}
return 0 ; //shouldn't happen
}
Edge
gesturecalculateedge ( double x0 , double y0 , double x1 , double y1 ) {
Edge horizontal = EdgeNone ;
Edge vertical = EdgeNone ;
if ( x0 < = edgesizex ) {
horizontal = EdgeLeft ;
} else if ( x0 > = screenwidth - edgesizex ) {
horizontal = EdgeRight ;
} else if ( x1 < = edgesizex ) {
horizontal = EdgeLeft ;
} else if ( x1 > = screenwidth - edgesizex ) {
horizontal = EdgeRight ;
}
if ( y0 < = edgesizey ) {
vertical = EdgeTop ;
} else if ( y0 > = screenheight - edgesizey ) {
vertical = EdgeBottom ;
} else if ( y1 < = edgesizey ) {
vertical = EdgeTop ;
} else if ( y1 > = screenheight - edgesizey ) {
vertical = EdgeBottom ;
}
if ( horizontal = = EdgeLeft & & vertical = = EdgeTop ) {
return CornerTopLeft ;
} else if ( horizontal = = EdgeRight & & vertical = = EdgeTop ) {
return CornerTopRight ;
} else if ( horizontal = = EdgeLeft & & vertical = = EdgeBottom ) {
return CornerBottomLeft ;
} else if ( horizontal = = EdgeRight & & vertical = = EdgeBottom ) {
return CornerBottomRight ;
} else if ( horizontal ! = EdgeNone ) {
return horizontal ;
} else {
return vertical ;
}
}
void
gestureexecute ( Swipe swipe , int nfingers ) {
gestureexecute ( Swipe swipe , int nfingers , Edge edge , Distance distance ) {
int i ;
for ( i = 0 ; i < gestsarrlen ; i + + ) {
if ( verbose ) {
fprintf ( stderr ,
" [Nfswipe/SwipeId]: Cfg (%d/%d) <=> Evt (%d/%d) \n " ,
gestsarr [ i ] . nfswipe , gestsarr [ i ] . swipe , nfingers , swipe
fprintf ( stderr ,
" [swipe]: Cfg(f= %d/s=%d/e=%d/d= %d) <=> Evt(f= %d/s=%d/e=%d/d= %d) \n " ,
gestsarr [ i ] . nfswipe , gestsarr [ i ] . swipe , gestsarr [ i ] . edge , gestsarr [ i ] . distance , nfingers , swipe , edge , distanc e
) ;
}
if ( gestsarr [ i ] . nfswipe = = nfingers & & gestsarr [ i ] . swipe = = swipe ) {
if ( gestsarr [ i ] . nfswipe = = nfingers & & gestsarr [ i ] . swipe = = swipe
& & gestsarr [ i ] . distance < = distance
& & ( gestsarr [ i ] . edge = = EdgeAny | | gestsarr [ i ] . edge = = edge | |
( ( edge = = CornerTopLeft | | edge = = CornerTopRight ) & & gestsarr [ i ] . edge = = EdgeTop ) | |
( ( edge = = CornerBottomLeft | | edge = = CornerBottomRight ) & & gestsarr [ i ] . edge = = EdgeBottom ) | |
( ( edge = = CornerTopLeft | | edge = = CornerBottomLeft ) & & gestsarr [ i ] . edge = = EdgeLeft ) | |
( ( edge = = CornerTopRight | | edge = = CornerBottomRight ) & & gestsarr [ i ] . edge = = EdgeRight )
)
) {
if ( verbose ) fprintf ( stderr , " Execute %s \n " , gestsarr [ i ] . command ) ;
execcommand ( gestsarr [ i ] . command ) ;
break ; //execute first match only
}
}
}
static int
static int
libinputopenrestricted ( const char * path , int flags , void * user_data )
{
int fd = open ( path , flags ) ;
return fd < 0 ? - errno : fd ;
}
static void
libinputcloserestricted ( int fd , void * user_data )
{
@ -141,6 +259,25 @@ swipereorient(Swipe swipe, int orientation) {
return swipe ;
}
Edge
edgereorient ( Edge edge , int orientation ) {
while ( orientation > 0 ) {
switch ( edge ) {
// 90deg per turn
case EdgeLeft : edge = EdgeTop ; break ;
case EdgeRight : edge = EdgeBottom ; break ;
case EdgeTop : edge = EdgeRight ; break ;
case EdgeBottom : edge = EdgeLeft ; break ;
case CornerTopLeft : edge = CornerTopRight ; break ;
case CornerTopRight : edge = CornerBottomRight ; break ;
case CornerBottomLeft : edge = CornerTopLeft ; break ;
case CornerBottomRight : edge = CornerBottomLeft ; break ;
}
orientation - - ;
}
return edge ;
}
void
touchdown ( struct libinput_event * e )
{
@ -197,17 +334,27 @@ touchup(struct libinput_event *e)
Swipe swipe = gesturecalculateswipe (
xstart [ slot ] , ystart [ slot ] , xend [ slot ] , yend [ slot ]
) ;
if ( nfpendingswipe = = 0 ) pendingswipe = swipe ;
Edge edge = gesturecalculateedge (
xstart [ slot ] , ystart [ slot ] , xend [ slot ] , yend [ slot ]
) ;
Distance distance = gesturecalculatedistance (
xstart [ slot ] , ystart [ slot ] , xend [ slot ] , yend [ slot ] , swipe
) ;
if ( nfpendingswipe = = 0 ) {
pendingswipe = swipe ;
pendingedge = edge ;
pendingdistance = distance ;
}
if ( pendingswipe = = swipe ) nfpendingswipe + + ;
resetslot ( slot ) ;
// All fingers up - check if within milisecond limit, exec, & reset
if ( nfdown = = 0 ) {
if (
timeoutms >
timeoutms >
( ( now . tv_sec - timedown . tv_sec ) * 1000000 + ( now . tv_nsec - timedown . tv_nsec ) / 1000 ) / 1000
) gestureexecute ( swipe , nfpendingswipe ) ;
) gestureexecute ( swipe , nfpendingswipe , edge , distance ) ;
nfpendingswipe = 0 ;
}
}
@ -238,7 +385,7 @@ run()
die ( " Couldn't set mode to capture events " ) ;
}
// E.g. initially invalidate every slot
// E.g. initially invalidate every slot
for ( i = 0 ; i < MAXSLOTS ; i + + ) {
xend [ i ] = NOMOTION ;
yend [ i ] = NOMOTION ;
@ -266,7 +413,7 @@ run()
}
libinput_unref ( li ) ;
}
int
main ( int argc , char * argv [ ] )
{
@ -300,10 +447,10 @@ main(int argc, char *argv[])
exit ( EXIT_FAILURE ) ;
}
gestpt = strtok ( argv [ + + i ] , " , " ) ;
for ( j = 0 ; gestpt ! = NULL & & j < 3 ; gestpt = strtok ( NULL , " , " ) , j + + ) {
for ( j = 0 ; gestpt ! = NULL & & j < 5 ; gestpt = strtok ( NULL , " , " ) , j + + ) {
switch ( j ) {
case 0 : gestsarr [ gestsarrlen - 1 ] . nfswipe = atoi ( gestpt ) ; break ;
case 1 :
case 1 :
if ( ! strcmp ( gestpt , " LR " ) ) gestsarr [ gestsarrlen - 1 ] . swipe = SwipeLR ;
if ( ! strcmp ( gestpt , " RL " ) ) gestsarr [ gestsarrlen - 1 ] . swipe = SwipeRL ;
if ( ! strcmp ( gestpt , " DU " ) ) gestsarr [ gestsarrlen - 1 ] . swipe = SwipeDU ;
@ -313,15 +460,40 @@ main(int argc, char *argv[])
if ( ! strcmp ( gestpt , " ULDR " ) ) gestsarr [ gestsarrlen - 1 ] . swipe = SwipeULDR ;
if ( ! strcmp ( gestpt , " DRUL " ) ) gestsarr [ gestsarrlen - 1 ] . swipe = SwipeDRUL ;
break ;
case 2 : gestsarr [ gestsarrlen - 1 ] . command = gestpt ; break ;
case 2 :
if ( ! strcmp ( gestpt , " L " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeLeft ;
if ( ! strcmp ( gestpt , " R " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeRight ;
if ( ! strcmp ( gestpt , " T " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeTop ;
if ( ! strcmp ( gestpt , " B " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeBottom ;
if ( ! strcmp ( gestpt , " TL " ) ) gestsarr [ gestsarrlen - 1 ] . edge = CornerTopLeft ;
if ( ! strcmp ( gestpt , " TR " ) ) gestsarr [ gestsarrlen - 1 ] . edge = CornerTopRight ;
if ( ! strcmp ( gestpt , " BL " ) ) gestsarr [ gestsarrlen - 1 ] . edge = CornerBottomLeft ;
if ( ! strcmp ( gestpt , " BR " ) ) gestsarr [ gestsarrlen - 1 ] . edge = CornerBottomRight ;
if ( ! strcmp ( gestpt , " N " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeNone ;
if ( ! strcmp ( gestpt , " * " ) ) gestsarr [ gestsarrlen - 1 ] . edge = EdgeAny ;
break ;
case 3 :
if ( ! strcmp ( gestpt , " L " ) ) gestsarr [ gestsarrlen - 1 ] . distance = DistanceLong ;
if ( ! strcmp ( gestpt , " M " ) ) gestsarr [ gestsarrlen - 1 ] . distance = DistanceMedium ;
if ( ! strcmp ( gestpt , " S " ) ) gestsarr [ gestsarrlen - 1 ] . distance = DistanceShort ;
if ( ! strcmp ( gestpt , " * " ) ) gestsarr [ gestsarrlen - 1 ] . distance = DistanceAny ;
break ;
case 4 : gestsarr [ gestsarrlen - 1 ] . command = gestpt ; break ;
}
}
} else {
fprintf ( stderr , " lisgd [-v] [-d /dev/input/0] [-o 0] [-t 200] [-r 20] [-m 400] [-g '1,LR,notify-send swiped left to right'] \n " ) ;
fprintf ( stderr , " lisgd [-v] [-d /dev/input/0] [-o 0] [-t 200] [-r 20] [-m 400] [-g '1,LR,L, notify-send swiped left to right from left edge '] \n " ) ;
exit ( 1 ) ;
}
}
//get display size
if ( ! ( dpy = XOpenDisplay ( 0 ) ) )
die ( " cannot open display " ) ;
screen = DefaultScreen ( dpy ) ;
screenwidth = DisplayWidth ( dpy , screen ) ;
screenheight = DisplayHeight ( dpy , screen ) ;
// E.g. no gestures passed on CLI - used gestures defined in config.def.h
if ( gestsarrlen = = 0 ) {
gestsarr = malloc ( sizeof ( gestures ) ) ;
@ -329,9 +501,11 @@ main(int argc, char *argv[])
memcpy ( gestsarr , gestures , sizeof ( gestures ) ) ;
}
// Modify gestures swipes based on orientation provided
for ( i = 0 ; i < gestsarrlen ; i + + )
// Modify gestures swipes based on orientation provided
for ( i = 0 ; i < gestsarrlen ; i + + ) {
gestsarr [ i ] . swipe = swipereorient ( gestsarr [ i ] . swipe , orientation ) ;
gestsarr [ i ] . edge = edgereorient ( gestsarr [ i ] . edge , orientation ) ;
}
run ( ) ;
return 0 ;