WG: Re: using uinput connect X to proprietary (TCP based) keyboard endpoint

Peter Hutterer peter.hutterer at who-t.net
Fri Oct 17 00:37:26 PDT 2014


On Fri, Oct 17, 2014 at 04:23:39AM +0200, Arne.Adams at t-online.de wrote:
> Hi,
> I am able to receive the input from the uinput device, if I explicitly select extension input events like this:
> 
> 
> int main(int argc, char** argv)
> {
>   Display* display = XOpenDisplay(NULL);
>   Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 1, 1, 500, 500,
>                                       0, BlackPixel(display, 0), BlackPixel(display, 0));
>   int ndevices = 0;
>   XDeviceInfo * devices = XListInputDevices(display, &ndevices);
>   int i = 0;
>   XDevice* uinputDev = NULL;
>   
>   for(;i < ndevices;++i)
>   {
>     if (strcmp(devices[i].name, "uinput-sample") == 0)
>     {
>       uinputDev = XOpenDevice(display, devices[i].id);
>     }
>   }
>   unsigned long keyPressInputClass;
>   unsigned long event_type_base;
>   DeviceKeyPress(uinputDev, event_type_base, keyPressInputClass);
>   XEventClass eventsOfInterest[] = {keyPressInputClass};
>   XSelectExtensionEvent(display, window, eventsOfInterest, 1);
>   XMapWindow(display, window);
>   XFlush(display);
>   XEvent report;
>   while (1)
>   {
>     XNextEvent(display, &report);
>     switch (report.type)
>     {
>     default:
>       printf("got a %d event\n", report.type);
>       break;
> 
>     }
>   }
>   XFlush(display);
>   sleep(5);
>   return (EXIT_SUCCESS);
> }
> This produces the following output:
> 
> got a 68 event
> got a 67 event
> ...
> 
> Now I have 2 questions:
> - can I get the same result with an XSelectInput call instead of XSelectExtensionEvent?

yes, the original program looked correct enough (except for the xflush())
but it's most likely some small error, either a missing sync, or something
similar. I do this rarely enough that it's always a bit of trial and error
for me anyway.

> - If not, in which header are the extension input types (68 and 67 in this case) defined?

You're supposed to use it as above. the event types are offset by the input
extension opcode, so e.g. a DeviceKeyPress is always opcode + 1. There is no
#define to use on the client side.

Cheers,
   Peter


> 
> Kind regards,
> Arne
> 
> 
> -----Original-Nachricht-----
> Betreff: WG: Re: using uinput connect X to proprietary (TCP based) keyboard endpoint
> Datum: Fri, 17 Oct 2014 02:09:14 +0200
> Von: "Arne.Adams at t-online.de" <Arne.Adams at t-online.de>
> An: xorg at lists.x.org
> 
> Hi Peter,
> thanks for the quick reply.
> Unfortunately that did not do the trick.
> When I use my laptop keyboard, I do see the output from my loop, however the simulated scancodes (currently that device just sends the scan code for the letter 'r') from my uinput device are not displayed.
> 
> This is the output from showkey:
> sudo showkey -s
> kb mode was ?UNKNOWN?
> [ if you are trying this under X, it might not work
> since the X server is also reading /dev/console ]
> 
> press any key (program terminates 10s after last keypress)...
> 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13....
> 
> This is the output from xinput:
> xinput test-xi2 uinput-sample | perl -lne ...
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> KeyPress 27 [r] 0x10 [Num_Lock]
> ...
> and this is the output without the perl filter:
> 
> xinput test-xi2 uinput-sample
> uinput-sample                           	id=15	[slave  keyboard (3)]
> 	Reporting 1 classes:
> 		Class originated from: 15. Type: XIKeyClass
> 		Keycodes supported: 248
> 
> EVENT type 2 (KeyPress)
>     device: 15 (15)
>     detail: 27
>     flags: repeat
>     root: 1113.00/127.00
>     event: 146.00/75.00
>     buttons:
>     modifiers: locked 0x10 latched 0 base 0 effective: 0x10
>     group: locked 0 latched 0 base 0 effective: 0
>     valuators:
>     windows: root 0x285 event 0x3400001 child 0x0
> EVENT type 2 (KeyPress)
>     device: 15 (15)
>     detail: 27
>     flags: repeat
>     root: 1069.00/129.00
>     event: 102.00/77.00
>     buttons:
>     modifiers: locked 0x10 latched 0 base 0 effective: 0x10
>     group: locked 0 latched 0 base 0 effective: 0
>     valuators:
>     windows: root 0x285 event 0x3400001 child 0x0
> EVENT type 2 (KeyPress)
>     device: 15 (15)
>     detail: 27
>     flags: repeat
>     root: 1061.00/129.00
>     event: 94.00/77.00
>     buttons:
>     modifiers: locked 0x10 latched 0 base 0 effective: 0x10
>     group: locked 0 latched 0 base 0 effective: 0
>     valuators:
>     windows: root 0x285 event 0x3400001 child 0x3400002
> EVENT type 2 (KeyPress)
>     device: 15 (15)
>     detail: 27
>     flags: repeat
>     root: 1058.00/130.00
>     event: 91.00/78.00
>     buttons:
>     modifiers: locked 0x10 latched 0 base 0 effective: 0x10
>     group: locked 0 latched 0 base 0 effective: 0
>     valuators:
>     windows: root 0x285 event 0x3400001 child 0x3400002
> 
> Kind regards,
> Arne
> 
> 
> -----Original-Nachricht-----
> Betreff: Re: using uinput connect X to proprietary (TCP based) keyboard endpoint
> Datum: Thu, 16 Oct 2014 17:12:45 +0200
> Von: Peter Hutterer <peter.hutterer at who-t.net>
> An: "Arne.Adams at t-online.de" <Arne.Adams at t-online.de>
> Cc: xorg at lists.x.org
> 
> On Thu, Oct 16, 2014 at 04:48:37AM +0200, Arne.Adams at t-online.de wrote:
> > Hi, 
> > I am trying to integrate a proprietary keyboard, sending linux scancodes via TCP.
> > My idea is to use uinput to forward the received keycodes to locally running applications (including the x server).
> > In my xorg.conf I have the following section:
> > 
> > Section "InputDevice"
> >     # to enable user defined virtual keyboard
> >     Identifier     "Keyboard1"
> >     Option         "Device" "/dev/input/event14"
> >     Driver         "evdev"
> > EndSection
> > where event14 is the event queue associated to the uinput simulated "device".
> > I do see the scancodes sent from my device with both commands:
> > - xinput test-xi2 --root
> > -  showkey -s
> > However I am not able to intercept the keyboard events in this simple X application
> > 
> > int main(int argc, char** argv)
> > {
> >   Display* display = XOpenDisplay(NULL);
> >   Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 1, 1, 500, 500,
> >                                       0, BlackPixel(display, 0), BlackPixel(display, 0));
> >   XSelectInput(display, window, KeyPressMask | KeyReleaseMask);
> >   XMapWindow(display, window);
> 
> 
> add a XFlush() here, that should do the trick.
> 
> Cheers,
>    Peter
> 
> >   XEvent report;
> >   while (1)
> >   {
> >     XNextEvent(display, &report);
> >     switch (report.type)
> >     {
> >     case KeyRelease:
> >       printf("got a KeyRelease event: %d, %d\n", report.xkey.keycode, report.xkey.state);
> >       break;
> >     case KeyPress:
> >       printf("got a KeyPress event: %d, %d\n", report.xkey.keycode, report.xkey.state);
> >       break;
> >     default:
> >       printf("got a %d event\n", report.type);
> >       break;
> > 
> >     }
> >   }
> >   XFlush(display);
> >   sleep(5);
> >   return (EXIT_SUCCESS);
> > }
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > _______________________________________________
> > xorg at lists.x.org: X.Org support
> > Archives: http://lists.freedesktop.org/archives/xorg
> > Info: http://lists.x.org/mailman/listinfo/xorg
> > Your subscription address: %(user_address)s
> > 
> 
> 
> 
> 
> 


More information about the xorg mailing list