@ -10,34 +10,72 @@
struct vkbd {
int fd ;
int pfd ;
} ;
static int create_virtual_keyboard ( const char * name )
static int create_virtual_pointer ( const char * name )
{
size_t i ;
uint16_t code ;
struct uinput_setup usetup ;
int fd = open ( " /dev/uinput " , O_WRONLY | O_NONBLOCK ) ;
if ( fd < 0 ) {
perror ( " open uinput " ) ;
perror ( " open " ) ;
exit ( - 1 ) ;
}
ioctl ( fd , UI_SET_EVBIT , EV_KEY ) ;
ioctl ( fd , UI_SET_EVBIT , EV_REL ) ;
ioctl ( fd , UI_SET_EVBIT , EV_KEY ) ;
ioctl ( fd , UI_SET_EVBIT , EV_SYN ) ;
for ( i = 0 ; i < KEY_MAX ; i + + ) {
if ( keycode_table [ i ] . name )
ioctl ( fd , UI_SET_KEYBIT , i ) ;
}
ioctl ( fd , UI_SET_RELBIT , REL_X ) ;
ioctl ( fd , UI_SET_RELBIT , REL_WHEEL ) ;
ioctl ( fd , UI_SET_RELBIT , REL_HWHEEL ) ;
ioctl ( fd , UI_SET_RELBIT , REL_Y ) ;
ioctl ( fd , UI_SET_RELBIT , REL_Z ) ;
for ( code = BTN_LEFT ; code < = BTN_TASK ; code + + )
ioctl ( fd , UI_SET_KEYBIT , code ) ;
for ( code = BTN_0 ; code < = BTN_9 ; code + + )
ioctl ( fd , UI_SET_KEYBIT , code ) ;
memset ( & usetup , 0 , sizeof ( usetup ) ) ;
usetup . id . bustype = BUS_USB ;
usetup . id . product = 0x1FAC ;
usetup . id . vendor = 0x0ADE ;
strcpy ( usetup . name , name ) ;
ioctl ( fd , UI_DEV_SETUP , & usetup ) ;
ioctl ( fd , UI_DEV_CREATE ) ;
return fd ;
}
static int create_virtual_keyboard ( const char * name )
{
size_t code ;
struct uinput_setup usetup ;
int fd = open ( " /dev/uinput " , O_WRONLY | O_NONBLOCK ) ;
if ( fd < 0 ) {
perror ( " open uinput " ) ;
exit ( - 1 ) ;
}
ioctl ( fd , UI_SET_EVBIT , EV_KEY ) ;
ioctl ( fd , UI_SET_EVBIT , EV_REL ) ;
ioctl ( fd , UI_SET_EVBIT , EV_SYN ) ;
for ( code = 0 ; code < KEY_MAX ; code + + ) {
/* skip mouse buttons to prevent X from identifying the virtual device as a mouse */
if ( ( ( code ) > = BTN_LEFT & & ( code ) < = BTN_TASK ) | |
( ( code ) > = BTN_0 & & ( code ) < = BTN_9 ) )
continue ;
if ( keycode_table [ code ] . name )
ioctl ( fd , UI_SET_KEYBIT , code ) ;
}
memset ( & usetup , 0 , sizeof ( usetup ) ) ;
usetup . id . bustype = BUS_USB ;
@ -56,6 +94,15 @@ struct vkbd *vkbd_init(const char *name)
struct vkbd * vkbd = calloc ( 1 , sizeof vkbd ) ;
vkbd - > fd = create_virtual_keyboard ( name ) ;
/*
* lazily initialize the virtual pointer to avoid presenting an
* external mouse if it is unnecessary . This can cause issues higher
* up the input stack ( e . g libinput touchpad disabling in the presence
* of an external mouse )
*/
vkbd - > pfd = 0 ;
return vkbd ;
}
@ -63,6 +110,10 @@ void vkbd_move_mouse(const struct vkbd *vkbd, int x, int y)
{
struct input_event ev ;
if ( ! vkbd - > pfd ) {
( ( struct vkbd * ) vkbd ) - > pfd = create_virtual_pointer ( " keyd virtual pointer " ) ;
}
if ( x ) {
ev . type = EV_REL ;
ev . code = REL_X ;
@ -71,7 +122,7 @@ void vkbd_move_mouse(const struct vkbd *vkbd, int x, int y)
ev . time . tv_sec = 0 ;
ev . time . tv_usec = 0 ;
write ( vkbd - > fd , & ev , sizeof ( ev ) ) ;
write ( vkbd - > p fd, & ev , sizeof ( ev ) ) ;
}
if ( y ) {
@ -82,14 +133,14 @@ void vkbd_move_mouse(const struct vkbd *vkbd, int x, int y)
ev . time . tv_sec = 0 ;
ev . time . tv_usec = 0 ;
write ( vkbd - > fd , & ev , sizeof ( ev ) ) ;
write ( vkbd - > p fd, & ev , sizeof ( ev ) ) ;
}
ev . type = EV_SYN ;
ev . code = 0 ;
ev . value = 0 ;
write ( vkbd - > fd , & ev , sizeof ( ev ) ) ;
write ( vkbd - > p fd, & ev , sizeof ( ev ) ) ;
}
void vkbd_send ( const struct vkbd * vkbd , uint16_t code , int state )