[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg
Subject:    Re: WG: Re: using uinput connect X to proprietary (TCP based) keyboard endpoint
From:       Peter Hutterer <peter.hutterer () who-t ! net>
Date:       2014-10-17 7:37:26
Message-ID: 20141017073726.GA29081 () jelly ! home
[Download RAW message or body]

On Fri, Oct 17, 2014 at 04:23:39AM +0200, Arne.Adams@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@t-online.de" <Arne.Adams@t-online.de>
> An: xorg@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@who-t.net>
> An: "Arne.Adams@t-online.de" <Arne.Adams@t-online.de>
> Cc: xorg@lists.x.org
> 
> On Thu, Oct 16, 2014 at 04:48:37AM +0200, Arne.Adams@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@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
> > 
> 
> 
> 
> 
> 
_______________________________________________
xorg@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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic