How to Grab Key Events
Guillaume Bouchard
guillaume.bouchard at insa-lyon.fr
Mon Apr 13 03:46:52 PDT 2009
On Mon, Apr 13, 2009 at 11:20:59AM +0200, VARADHARAJAN RAVINDRANATH wrote:
> I am a newbie in Xorg. I have a requirement wherein I need to grab
> the key events in my X11 application even though it does not have focus.
> This application in turn will do some manipulation in the received key
> and will send the updated key press event to other X11 clients using
> XSendEvent. This is some thing like a window manager implementation
> where all X11 applications will be registered as clients to my
> application. Hence, my application will be running as a background
> process. So,when Xorg receives a key press, it should NOT send the
> keypress event to the focused client (even though it has registered for
> that event). It should first send it to my application.
I had the *same* problem some time ago.
The solution that I use is very basics, but it feet my needs :
1) disable the keyboard in evdev (I hope you use it)
2) open (on linux) the evdev file device and read for it in your
application.
I just realize that when I found the answer, I only send my greeting
message with the solution to the person who answer me, sorry for the ML,
now the answer is available for everyone.
1) To blacklist your device :
file : /etc/hal/fdi/preprobe/10-blacklist.fdi
<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
<match key="info.category" contains="input">
<match key="input.product" contains="TechScan">
<merge key="info.ignore" type="bool">true</merge>
</match>
</match>
</device>
</deviceinfo>
(TechScan is something specific on my barcode reader usb info, up to you
to find something specific to your device with hal-device)
2) Python code used to read the special device. Because I use a very
simple device, It's not long, but in your case you will have te write
something more complex
import struct
# ---------------------------------------------------------------
# see include/linux/input.h
EVENT_KEY = 1
EVENT_RELEASED = 1
# an event is 8 + 2 + 2 + 4 char because of :
# struct input_event {
# struct timeval time; 8
# __u16 type; ushort
# __u16 code; ushort
# __s32 value; uint
# ---------------------------------------------------------------
def read_event(fp):
event = fp.read(8+2+2+4)
tv_sec,tv_usec = struct.unpack('ll',event[:8])
type,code,value = struct.unpack('HHL',event[8:])
return tv_sec,tv_usec,type,code,value
DEV = '/dev/input/by-id/'
DEVICE = 'usb-TechScan_Korea_Barcode_reader_v38b_-event-kbd'
PATH = DEV+DEVICE
fp = open(PATH)
while True:
tv_sec,tv_usec,type,code,value = read_event(fp)
if type == EVENT_KEY:
if value == EVENT_RELEASED:
if code == 28:
print "RET" # 28 is return
else:
# I use a barcode reader, so every char is a number,
# see include/linux/input.h for the formula
print (code-1)%10,
When i wrote these, I just realize that your need are not exactly the
same than my. I think you can use any "grab" function of you toolkit
(gtk does this pretty well) to grab every key:
http://www.pygtk.org/pygtk2reference/gdk-functions.html#function-gdk--keyboard-grab
I let the other part of the answer because it can *perhaps* help
someone.
Good luck.
--
Guillaume
More information about the xorg
mailing list