views:

1033

answers:

6

I am trying to write a cross-platform python program that would run in the background, monitor all keyboard events and when it sees some specific shortcuts, it generates one or more keyboard events of its own. For example, this could be handy to have Ctrl-@ mapped to "my.email@address", so that every time some program asks me for my email address I just need to type Ctrl-@.

I know such programs already exist, and I am reinventing the wheel... but my goal is just to learn more about low-level keyboard APIs. Moreover, the answer to this question might be useful to other programmers, for example if they want to startup an SSH connection which requires a password, without using pexpect.

Thanks for your help.

Note: there is a similar question but it is limited to the Windows platform, and does not require python. I am looking for a cross-platform python api. There are also other questions related to keyboard events, but apparently they are not interested in system-wide keyboard events, just application-specific keyboard shortcuts.

Edit: I should probably add a disclaimer here: I do not want to write a keylogger. If I needed a keylogger, I could download one off the web a anyway. ;-)

+3  A: 

There is no such API. My solution was to write a helper module which would use a different helper depending on the value of os.name.

On Windows, use the Win32 extensions.

On Linux, things are a bit more complex since real OSes protect their users against keyloggers[*]. So here, you will need a root process which watches one of[] the handles in /dev/input/. Your best bet is probably looking for an entry below /dev/input/by-path/ which contains the strings "kbd" or "keyboard". That should work in most cases.

[*]: Jeez, not even my virus/trojan scanner will complain when I start a Python program which hooks into the keyboard events...

Aaron Digulla
Very clear answer, thank you very much. :-)
MiniQuark
A: 

Cross-platform UI libraries such as Tkinter or wxPython have API for keyboard events. Using these you could map «CTRL» + «@» to an action.

vartec
Unfortunately, this will not give me a system-wide keyboard monitor, just an application-specific one.
MiniQuark
+1  A: 

On linux, you might want to have a look at pykeylogger. For some strange reason, reading from /dev/input/.... doesn't always work when X is running. For example it doesn't work on ubuntu 8.10. Pykeylogger uses xlib, which works exactly when the other way doesn't. I'm still looking into this, so if you find a simpler way of doing this, please tell me.

Kim
+1  A: 

As the guy that wrote the original pykeylogger linux port, I can say there isn't really a cross platform one. Essentially I rewrote the pyhook API for keyboard events to capture from the xserver itself, using the record extension. Of course, this assumes the record extension is there, loaded into the x server.

From there, it's essentially just detecting if you're on windows, or linux, and then loading the correct module for the OS. Everything else should be identical.

Take a look at the pykeylogger source, in pyxhook.py for the class and implimentation. Otherwise, just load that module, or pyhook instead, depending on OS.

+1  A: 

I've made a few tests on Ubuntu 9.10. pykeylogger doesn't seems to be working. I've tryied to change the /etc/X11/xorg.conf in order to allow module to be loaded but in that specific version of ubuntu there is no xorg.conf. So, in my opiniion pykelogger is NOT working on ubuntu 9.10 !!

PeiMei
Me too. I can't get pykeylogger running on ubuntu 9.10
Rory
For the record I think it's this bug here that prevents pykeylogger from working on ubuntu 9.10 https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/315456
Rory
A: 

Under Linux it's possible to do this quite easily with Xlib. See this page for details:

http://www.larsen-b.com/Article/184.html