1

Using this short snippet of code I am able to capture events from the keyboard (/dev/input/event1) and print them properly. However, sending them to the Xvfb display using XTestFakeKeyEvent does not work even if XTestFakeKeyEvent returns successful.

char devname[] = "/dev/input/event1";
int device = open(devname, O_RDONLY);
struct input_event ev;
signal(SIGINT, INThandler);
Display *dpy = XOpenDisplay(NULL);
if (!dpy) {fprintf(stderr, "unable to connect to display");return 7;}
while(1)
{
        read(device,&ev, sizeof(ev));
        printf("Key: %i State: %i\n",ev.code,ev.value);
        if(ev.code!=4)
                if(!(XTestFakeKeyEvent(dpy, ev.code, ev.value, 0)))
                        {fprintf(stderr, "unable to send keystroke\n");return 7;};
}

I thought the problem was with the compatibility between Xvfb and XTestFakeKeyEvent but I am able to send keystrokes to the display using the xdotool program in the shell, which uses XTestFakeKeyEvent. It's possible that I'm doing this wrong, I'm not familiar with X11 programming. Thank you in advance.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Az ayd
  • 11
  • 1

2 Answers2

0

I personally use Xvfb and XTestFakeKeyEvent together and they're compatible.

You seem to be giving ev.value raw into XTest. ev.value is 1 for keydown and 0 for keyup. However XTest has these codes defined: (source)

FAKE_EVENT_TYPE
     2     KeyPress
     3     KeyRelease
     4     ButtonPress
     5     ButtonRelease
     6     MotionNotify

=> KeyPress needs to be 2 and release needs to be 3. Also I'm not sure about the function argument order, you should validate that too if it still doesn't work. :)

p.s. you might be interested to read https://joonas.fi/2020/12/attach-a-keyboard-to-a-docker-container/

joonas.fi
  • 7,478
  • 2
  • 29
  • 17
  • OP uses `XTestFakeKeyEvent()` which takes bool as third parameter True for key press False for key release. source you sent is for x11 network protocol, which OP doesnt use directly. – fsdfhdsjkhfjkds Dec 24 '22 at 17:46
0

Most of X* functions are actually just writes itself to buffer. For send that buffer to your xserver you need to call XFlush() or other similar function.

So just call XFlush() after your XTestFakeKeyEvent().

manual page of XFlush

Check open() and read() return values for error check.

Be sure ev.type is key related by adding your code if(ev.type != EV_KEY) continue; after read()

XTestFakeKeyEvent() takes keycode but ev.code is probably scancode. You need to translate scancode into keycode to use it.

ev.value is also can give repeat value which is 2 but XTestFakeKeyEvent() doesn't have repeat so you can give !!ev.value to it.

fsdfhdsjkhfjkds
  • 308
  • 1
  • 9