Virtual Keyboard (Linux/libevdev) - sending events

32 views
Skip to first unread message

hanusek.w...@gmail.com

unread,
Jul 13, 2017, 8:05:13 AM7/13/17
to BeagleBoard

Trying to implement a virtual keyboard. The program sends a keystroke event in the 5 second cycle. Its working on PC (Ubuntu Linux). The problem is that nothing is displayed on BBB.

Plaftorm Beaglebone Black, Debian Jessie:

debian@beaglebone:~$ uname -a
Linux beaglebone 4.9.9-ti-r22 #1 SMP PREEMPT Mon Feb 13 18:39:00 UTC 2017 armv7l GNU/Linux
Code:#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <linux/uinput.h>

/* emit function is identical to of the first example */

void emit(int fd, int type, int code, int val)
{
 
struct input_event ie;

 ie
.type = type;
 ie
.code = code;
 ie
.value = val;
 
/* timestamp values below are ignored */
 ie
.time.tv_sec = 0;
 ie
.time.tv_usec = 0;

 
int res = write(fd, &ie, sizeof(ie));
 printf
("emit write bytes=%d fd=%d code=%d val=%d\n",res, fd, code, val);
}

int main(void)
{
 
struct uinput_user_dev uud;
 
int version, rc, fd;

 fd
= open("/dev/uinput", O_WRONLY | O_NONBLOCK);
 printf
("fd=%d\n",fd);



 
/*
 * The ioctls below will enable the device that is about to be
 * created, to pass key events, in this case the space key.
 */

 
int i1 = ioctl(fd, UI_SET_EVBIT, EV_KEY);
 
int i2 = ioctl(fd, UI_SET_EVBIT, EV_SYN);
 
int i3 = ioctl(fd, UI_SET_KEYBIT, KEY_D);
 
int i4 = ioctl(fd, UI_SET_KEYBIT, KEY_U);
 
int i5 = ioctl(fd, UI_SET_KEYBIT, KEY_P);
 
int i6 = ioctl(fd, UI_SET_KEYBIT, KEY_A);

// printf("ioctl = %d, %d, %d ,%d , %d, %d\n", i1,i2,i3,i4,i5,i6);

 memset
(&uud, 0, sizeof(uud));
 snprintf
(uud.name, UINPUT_MAX_NAME_SIZE, "uinput-keyboard");
 uud
.id.bustype = BUS_HOST;
 uud
.id.vendor = 0x1;
 uud
.id.product = 0x2;
 uud
.id.version = 1;

 write
(fd, &uud, sizeof(uud));
 sleep
(2);

 
int i = ioctl(fd, UI_DEV_CREATE);
 printf
("dev create =%d\n", i);

 sleep
(2);

 
/* Key press, report the event, send key release, and report again */
for(;;)
{
 emit
(fd, EV_KEY, KEY_D, 1);
 emit
(fd, EV_SYN, SYN_REPORT, 1);
 sleep
(1);
 emit
(fd, EV_KEY, KEY_D, 0);
 emit
(fd, EV_SYN, SYN_REPORT, 0);

 emit
(fd, EV_KEY, KEY_U, 1);
 emit
(fd, EV_SYN, SYN_REPORT, 0);
 emit
(fd, EV_KEY, KEY_U, 0);
 emit
(fd, EV_SYN, SYN_REPORT, 0);

 emit
(fd, EV_KEY, KEY_P, 1);
 emit
(fd, EV_SYN, SYN_REPORT, 0);
 emit
(fd, EV_KEY, KEY_P, 0);
 emit
(fd, EV_SYN, SYN_REPORT, 0);

 emit
(fd, EV_KEY, KEY_A, 1);
 emit
(fd, EV_SYN, SYN_REPORT, 0);
 emit
(fd, EV_KEY, KEY_A, 0);
 emit
(fd, EV_SYN, SYN_REPORT, 0);

 sleep
(5);
}
 ioctl
(fd, UI_DEV_DESTROY);

 close
(fd);
 
return 0;
}
/dev/input/event1
   bustype : BUS_HOST
   vendor  : 0x1
   product : 0x2
   version : 1
   name    : "uinput-keyboard"
   bits ev : (null) (null)
root@beaglebone:/home/debian/KeyEvent# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:  tps65217_pwr_but
/dev/input/event1:  uinput-keyboard
Select the device event number [0-1]: 1
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x2 version 0x1
Input device name: "uinput-keyboard"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 22 (KEY_U)
    Event code 25 (KEY_P)
    Event code 30 (KEY_A)
    Event code 32 (KEY_D)
Properties:
Testing ... (interrupt to exit)
Event: time 1499869756.493690, type 1 (EV_KEY), code 32 (KEY_D), value 1
Event: time 1499869756.493690, -------------- SYN_REPORT ------------
Event: time 1499869757.494181, type 1 (EV_KEY), code 32 (KEY_D), value 0
Event: time 1499869757.494181, -------------- SYN_REPORT ------------
Event: time 1499869757.494304, type 1 (EV_KEY), code 22 (KEY_U), value 1
Event: time 1499869757.494304, -------------- SYN_REPORT ------------
Event: time 1499869757.494370, type 1 (EV_KEY), code 22 (KEY_U), value 0
Event: time 1499869757.494370, -------------- SYN_REPORT ------------
Event: time 1499869757.494434, type 1 (EV_KEY), code 25 (KEY_P), value 1
Event: time 1499869757.494434, -------------- SYN_REPORT ------------
Event: time 1499869757.494495, type 1 (EV_KEY), code 25 (KEY_P), value 0
Event: time 1499869757.494495, -------------- SYN_REPORT ------------
Event: time 1499869757.494558, type 1 (EV_KEY), code 30 (KEY_A), value 1
Event: time 1499869757.494558, -------------- SYN_REPORT ------------
Event: time 1499869757.499785, type 1 (EV_KEY), code 30 (KEY_A), value 0
Event: time 1499869757.499785, -------------- SYN_REPORT ------------
Event: time 1499869762.502378, type 1 (EV_KEY), code 32 (KEY_D), value 1
Event: time 1499869762.502378, -------------- SYN_REPORT ------------
Event: time 1499869763.225387, type 1 (EV_KEY), code 32 (KEY_D), value 0
Event: time 1499869763.225402, -------------- SYN_REPORT ------------
expected 16 bytes, got -1

hanusek.w...@gmail.com

unread,
Jul 13, 2017, 8:05:13 AM7/13/17
to BeagleBoard

I'm trying to implement a virtual keyboard. 

The program sends a keystroke event in the 5 second cycle. Its working on PC (Ubuntu Linux). The problem is that nothing is displayed on BBB.


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/uinput.h>


void emit(int fd, int type, int code, int val)
{
   
struct input_event ie;
   ie
.type = type;
   ie
.code = code;
   ie
.value = val;

   
/* timestamp values below are ignored */
   ie
.time.tv_sec = 0;
   ie
.time.tv_usec = 0;
   
int res = write(fd, &ie, sizeof(ie));
   printf
("emit write bytes=%d fd=%d code=%d val=%d\n",res, fd, code, val);
}


int main(void)
{

   
struct uinput_user_dev uud;

   
int fd;

   fd
= open("/dev/uinput", O_WRONLY | O_NONBLOCK);
   printf
("fd=%d\n",fd);


   
int i1 = ioctl(fd, UI_SET_EVBIT, EV_KEY);

   
int i2 = ioctl(fd, UI_SET_EVBIT, EV_SYN);
   
int i3 = ioctl(fd, UI_SET_KEYBIT, KEY_D);
   
int i4 = ioctl(fd, UI_SET_KEYBIT, KEY_U);
   
int i5 = ioctl(fd, UI_SET_KEYBIT, KEY_P);
   
int i6 = ioctl(fd, UI_SET_KEYBIT, KEY_A);


   memset
(&uud, 0, sizeof(uud));

   snprintf
(uud.name, UINPUT_MAX_NAME_SIZE, "uinput-keyboard");

   uud
.id.bustype = BUS_HOST;
   uud
.id.vendor  = 0x1;
   uud
.id.product = 0x2;
   uud
.id.version = 1;

   write
(fd, &uud, sizeof(uud));
   sleep
(2);

   
int i = ioctl(fd, UI_DEV_CREATE);
   printf
("dev create =%d\n", i);

   sleep
(2);

for(;;)
{

   emit
(fd, EV_KEY, KEY_D, 1);
   emit
(fd, EV_SYN, SYN_REPORT, 1);

   emit
(fd, EV_KEY, KEY_D, 0);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_U, 1);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_U, 0);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_P, 1);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_P, 0);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_A, 1);
   emit
(fd, EV_SYN, SYN_REPORT, 0);
   emit
(fd, EV_KEY, KEY_A, 0);
   emit
(fd, EV_SYN, SYN_REPORT, 0);

   sleep
(5);

}
   ioctl
(fd, UI_DEV_DESTROY);

   close
(fd);
   
return 0;
}


lsinput - ev bit are correct? :

/dev/input/event1
   bustype : BUS_HOST
   vendor  : 0x1
   product : 0x2
   version : 1
   name    : "uinput-keyboard"
   bits ev : (null) (null)

Evtest - sending event to kernel (its OK):

Plaftorm Beaglebone Black, Debian Jessie:

Reply all
Reply to author
Forward
0 new messages