Capture e interprete o evento XI2 RawKeyPress com python

Auto-resolvido

É postado abaixo como resposta.

Tentando conseguir o quexinput test-xi2 --root imprime com python xlib.
Usando a versão 1.9 do github:https://github.com/python-xlib/python-xlib

event._data["data"] conteúdo para aaaaoo:

a<class 'Xlib.ext.ge.GenericEvent'>(data = b'\t\x00\xa9!v\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b'\x03\x00\xa9!v\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
a<class 'Xlib.ext.ge.GenericEvent'>(data = b"\t\x00A'v\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b"\x03\x00A'v\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
a<class 'Xlib.ext.ge.GenericEvent'>(data = b'\t\x00\xa9Ev\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b'\x03\x00\xa9Ev\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
a<class 'Xlib.ext.ge.GenericEvent'>(data = b"\t\x00\xea\x9dv\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b"\x03\x00\xea\x9dv\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
o<class 'Xlib.ext.ge.GenericEvent'>(data = b"\t\x002\xb4v\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b"\x03\x002\xb4v\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
o<class 'Xlib.ext.ge.GenericEvent'>(data = b"\t\x00\xba\xb8v\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>(data = b"\x03\x00\xba\xb8v\x17'\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sequence_number = 15, length = 2, evtype = 13, extension = 131, type = 35)

Código usado para obter o acima, embora algumas linhas precisem ser comentadas para reproduzir a saída acima.

from Xlib import X, XK, display, error
from Xlib.ext import xinput
from Xlib.protocol import rq
from Xlib import protocol
from Xlib import Xutil



class Test:
    def __init__(self):
        self.dpy_input = display.Display(None)
        #try setting events to capture
        root = self.dpy_input.screen().root
        root.xinput_select_events([(xinput.AllDevices, xinput.RawKeyPressMask)])

        extension_info = self.dpy_input.query_extension('XInputExtension')
        self.xinput_major = extension_info.major_opcode
        self.version_info = self.dpy_input.xinput_query_version()
        print('Found XInput version %u.%u' %(
            self.version_info.major_version,
            self.version_info.major_version,) )

    def run(self):
        while True:
            event = self.dpy_input.next_event()
            if event is None:
                break
            if event.type != self.dpy_input.extension_event.GenericEvent:
                break
            if event.evtype != xinput.RawKeyPress:
                break

            print (event.__class__)
            print(event.__dict__)
            print(event)

            estruct = self.dpy_input.display.event_classes.get(
                rq.byte2int(event._binary) & 0x7f, protocol.event.AnyEvent)
            print(estruct)

            e , d= rq.EventField(None).parse_binary_value(
                event._binary, self.dpy_input.display, None, None)
            print (e)


            e , d= rq.EventField(None).parse_binary_value(
                event._data["data"], self.dpy_input.display, None, None)
            print (e)

            break

if __name__ == "__main__":
    t = Test()
    t.run()

Saída em cima de uma pressione o botão:

Found XInput version 2.2
<class 'Xlib.ext.ge.GenericEvent'>
{'_data': {'sequence_number': 15, 'extension': 131, 'length': 2, 'send_event': False, 'data': b'\t\x00\xbf\xbdc\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'evtype': 13, 'type': 35}, '_binary': b'#\x83\x0f\x00\x02\x00\x00\x00\r\x00'}
<class 'Xlib.ext.ge.GenericEvent'>(sequence_number = 15, extension = 131, length = 2, data = b'\t\x00\xbf\xbdc\x17&\x00\x00\x00\t\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', evtype = 13, type = 35)
<class 'Xlib.ext.ge.GenericEvent'>
<class 'Xlib.ext.ge.GenericEvent'>(sequence_number = 15, extension = 131, length = 2, data = b'', evtype = 13, type = 35)
aTraceback (most recent call last):
  File "/home/d/PycharmProjects/GUIConfigurator/xi2_test.py", line 54, in <module>
    t.run()
  File "/home/d/PycharmProjects/GUIConfigurator/xi2_test.py", line 47, in run
    event._data["data"], self.dpy_input.display, None, None)
  File "/home/d/PycharmProjects/GUIConfigurator/Xlib/protocol/rq.py", line 859, in parse_binary_value
    return estruct(display = display, binarydata = data[:32]), data[32:]
  File "/home/d/PycharmProjects/GUIConfigurator/Xlib/protocol/rq.py", line 1403, in __init__
    rawdict = 1)
  File "/home/d/PycharmProjects/GUIConfigurator/Xlib/protocol/rq.py", line 1146, in parse_binary
    val = struct.unpack(self.static_codes, data[:self.static_size])
struct.error: unpack requires a bytes object of length 32  
Pergunta, questão

O que está emevent._data["data"] e como posso torná-lo legível por humanos?

questionAnswers(1)

yourAnswerToTheQuestion