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