使用python捕获和解释XI2 RawKeyPress事件 [英] Capture and interpret XI2 RawKeyPress event with python
问题描述
它作为答案发布在下面.
It's posted below as an answer.
尝试使用python xlib获取xinput test-xi2 --root
打印的内容.
使用来自github的1.9版: https://github.com/python-xlib/python-xlib
Trying to get what xinput test-xi2 --root
prints with python xlib.
Using version 1.9 from github: https://github.com/python-xlib/python-xlib
event._data["data"]
内容:
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)
用于获取以上内容的代码;尽管需要注释掉某些行才能重现上面的输出.
Code used to get the above;though some lines need to be commented out to reproduce the output above.
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()
按a
键时输出:
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
问题
event._data["data"]
中的内容是什么,我如何使其易于阅读?
Question
What is in event._data["data"]
and how can I make it human readable?
推荐答案
已成功破解了RawKeyPress事件中的部分二进制数据.
进阶是相当……虽然不太优雅,但我不知道真正的黑客是怎么做到的.
Managed to hack some portion of the binary data in RawKeyPress event.
The precess was rather... inelegant though, I wonder how real hackers do this.
from Xlib import X, XK, display, error
from Xlib.ext import xinput
import time
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.AllMasterDevices, 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)
b = event._data["data"]
device = b[0:1]
print("device:%d" % ( int.from_bytes(device,"little")))
# value at b[1] seems like padding, always 0.
# 7th byte contains x11 keycode
keycode = b[6]
print("keycode:"+str(keycode))
# Not certain as to what this really is.
timestamp = b[2:6] # four bytes int
print('timestamp:'+str(int.from_bytes(timestamp,"little")))
# Not certain as to what this really is.
valuators = b[7:9] # 2 bytes, short int
print("valuators:" + str(int.from_bytes(valuators,"little")))
device_id = b[10:11] # 2 bytes, short int
print("device id:" + str(int.from_bytes(device_id,"little")))
if __name__ == "__main__":
t = Test()
t.run()
我将python脚本输出与xinput test-xi2 --root
的输出进行了A按键比较.
I compared the python script output with the output from xinput test-xi2 --root
for a A keypress.
Python:
b'\x03\x00H\x8a\xd9\x1c&\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
xinput:
EVENT type 14 (RawKeyRelease)
device: 3 (12)
detail: 38
valuators:
现在脚本将打印:
Found XInput version 2.2
<class 'Xlib.ext.ge.GenericEvent'>(evtype = 13, data = b'\x03\x004=A\x1d&\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type = 35, length = 2, extension = 131, sequence_number = 15)
device:3
keycode:38
timestamp:490814772
valuators:0
device id:12
尽管它还很不完整,但是我不得不离开这里,因为我知道RawKeyPress事件不能提供我想要的东西:隐藏用法ID或Linux内核扫描代码.
Although it's rather incomplete still, I have to leave off here as now I know RawKeyPress event does not provide what I want: hid usage id or linux kernel scancode.
这篇关于使用python捕获和解释XI2 RawKeyPress事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!