@ -26,44 +26,56 @@
*
* We could make this cleaner by creating a single file descriptor via epoll
* but this would break FreeBSD compatibility without a dedicated kqueue
* implementation . A thread based approach was also considered ,
* but inter - thread communication adds too much overhead ( ~ 100u s ) .
* implementation . A thread based approach was also considered , but
* inter - thread communication adds too much overhead ( ~ 100u s ) .
*
* Overview :
*
* A ' devmon ' is a file descriptor which can be created with devmon_create ( )
* and subsequently monitored for new devices read with devmon_read_device ( ) .
*
* A ' device ' always corresponds to a keyboard from which activity can be
* monitored with device - > fd and events subsequently read using
* A ' device ' always corresponds to a keyboard or mouse from which activity can
* be monitored with device - > fd and events subsequently read using
* device_read_event ( ) .
*
* If the event returned by device_read_event ( ) is of type DEV_REMOVED then the
* corresponding device should be considered invalid by the caller .
*/
static int is_keyboard ( int fd )
/*
* returns 1 if keyboard , 2 if mouse , and 0 if neither .
*/
static int device_type ( int fd )
{
uint32_t keymask ;
uint32_t mask [ BTN_LEFT / 32 + 1 ] = { 0 } ;
if ( ioctl ( fd , EVIOCGBIT ( EV_KEY , sizeof keymask ) , & key mask) < 0 ) {
if ( ioctl ( fd , EVIOCGBIT ( EV_KEY , ( BTN_LEFT / 32 + 1 ) * 4 ) , mask ) < 0 ) {
perror ( " ioctl " ) ;
return 0 ;
}
/* The first 31 bits correspond to [KEY_ESC-KEY_S] */
return keymask = = 0xFFFFFFFE ;
if ( mask [ 0 ] = = 0xFFFFFFFE )
return 1 ;
else if ( mask [ BTN_LEFT / 32 ] > > BTN_LEFT % 32 )
return 2 ;
else
return 0 ;
}
static int device_init ( const char * path , struct device * dev )
{
int fd ;
int type ;
if ( ( fd = open ( path , O_RDONLY | O_NONBLOCK , 0600 ) ) < 0 ) {
fprintf ( stderr , " failed to open %s \n " , path ) ;
return - 1 ;
}
if ( is_keyboard ( fd ) ) {
type = device_type ( fd ) ;
if ( type ) {
struct input_id info ;
if ( ioctl ( fd , EVIOCGNAME ( sizeof ( dev - > name ) ) , dev - > name ) = = - 1 ) {
@ -80,6 +92,7 @@ static int device_init(const char *path, struct device *dev)
dev - > path [ sizeof ( dev - > path ) - 1 ] = 0 ;
dev - > fd = fd ;
dev - > is_keyboard = type = = 1 ;
dev - > vendor_id = info . vendor ;
dev - > product_id = info . product ;
@ -254,6 +267,8 @@ struct device_event *device_read_event(struct device *dev)
ev . code = KEYD_MOUSE_2 ;
else if ( ev . code = = KEY_FN )
ev . code = KEYD_FN ;
else if ( ev . code > = BTN_DIGI & & ev . code < = BTN_TOOL_QUADTAP )
;
else {
fprintf ( stderr , " ERROR: unsupported evdev code: 0x%x \n " , ev . code ) ;
return NULL ;