Input Device Routing

Lots of different (USB) devices come up as HID devices in Linux.  That is, they appear to the system as if they are keybords and mice.  You plug them in, and X deals with them the normal way.

When they output stuff, X will receive the events and characters will appear in whatever program has the focus.

But what if you don’t want that?  If you have a barcode scanner, you probably want the output from that device to go to one specific program, and not to whatever has the focus.  First setting focus on the barcode program and then scanning sounds just ridonculous.

Unfortunately, it seems like this isn’t trivial to do.  Unless something has changed lately, or my bing-fu is bad, there still doesn’t seem to be a simple “point-the-output-from-this-device-to-this-program”.

So here’s a long-winded detailed howto for doing this under Debian Squeeze, but I think it should work under any Linux version.

First of all, X will read all the HID devices under /dev/input/event* only.  (The details are in
/usr/share/X11/xorg.conf.d/10-evdev.conf.)  So if you make your device show up under a different name, X won’t know about it.

Doing device name trickery is what we have udev for.

In the following example, I’m using a wireless keypad device from Ortek.

Create a file called something like /etc/udev/rules.d/95-keyboard.rules with the following content:

# Ortek RF keypad
KERNEL==”event*”, ATTRS{idVendor}==”05a4″, ATTRS{idProduct}==”3270″, MODE=”0644″, NAME=”input/ortek%n”

This tells udev that if we plug in a device that would have been called “event*”, with that vendor/id pair, then call it “input/ortek*” instead.

You find the vendor/id pair by using lsusb:

stories:~# lsusb | grep -i Ortek
Bus 001 Device 051: ID 05a4:3270 Ortek Technology, Inc.

udev will complain bitterly:

Jan 12 12:58:27 stories udevd-work[16145]: kernel-provided name ‘input/event8’ and NAME= ‘input/ortek8’ disagree, please use SYMLINK+= or change the kernel to provide the proper name

Yeah, what are you gonna do about it, udev?  Start crying?  Go ahead.

stories:~# ls -l /dev/input/ortek*
crw-r–r– 1 root root 13, 71 Jan 12 12:58 /dev/input/ortek7
crw-r–r– 1 root root 13, 72 Jan 12 12:58 /dev/input/ortek8

See?  It works.

Now we have an input device that X doesn’t know about, so we can snoop its output without the data appearing spuriously in whatever window is active.

For snooping we use evrouter.  In debug mode it will tell us what the events we get are:

stories:~# /home/larsi/bin/evrouter-64 -d /dev/input/ortek*
device  0: /dev/input/ortek7:   RF USB Device
device  1: /dev/input/ortek8:   RF USB Device
”  RF USB Device” “/dev/input/ortek7” none key/55 “fill this in!”
”  RF USB Device” “/dev/input/ortek7” none key/98 “fill this in!”
”  RF USB Device” “/dev/input/ortek7” none key/28 “fill this in!”

So we need to create an evrouter.rc file that maps the events to whatever we want to have happen.

This is the file that maps all the keypad keys on the Ortek device:

“.*” “/dev/input/ortek.*” none key/15 “Shell/getchar TAB”
“.*” “/dev/input/ortek.*” none key/98 “Shell/getchar /”
“.*” “/dev/input/ortek.*” none key/55 “Shell/getchar *”
“.*” “/dev/input/ortek.*” none key/14 “Shell/getchar BACK”

“.*” “/dev/input/ortek.*” none key/71 “Shell/getchar 7”
“.*” “/dev/input/ortek.*” none key/72 “Shell/getchar 8”
“.*” “/dev/input/ortek.*” none key/73 “Shell/getchar 9”
“.*” “/dev/input/ortek.*” none key/74 “Shell/getchar -“

“.*” “/dev/input/ortek.*” none key/75 “Shell/getchar 4”
“.*” “/dev/input/ortek.*” none key/76 “Shell/getchar 5”
“.*” “/dev/input/ortek.*” none key/77 “Shell/getchar 6”
“.*” “/dev/input/ortek.*” none key/78 “Shell/getchar +”

“.*” “/dev/input/ortek.*” none key/79 “Shell/getchar 1”
“.*” “/dev/input/ortek.*” none key/80 “Shell/getchar 2”
“.*” “/dev/input/ortek.*” none key/81 “Shell/getchar 3”
“.*” “/dev/input/ortek.*” none key/28 “Shell/getchar ENTER”

“.*” “/dev/input/ortek.*” none key/82 “Shell/getchar 0”
“.*” “/dev/input/ortek.*” none key/83 “Shell/getchar .”

You can, of course, do anything with these events.  For this particular use case, though, I want to collect a single line, and then act upon it when I hit the ENTER key.  So I’ve written a tiny program called getchar that collects keys, and then acts upon the string when it gets ENTER.

So start evrouter:

evrouter -c ~/.evrouter-keypad.rc /dev/input/ortek*

And there you are.  Couldn’t be…  er…  perhaps it could be simpler.

Perhaps evrouter should be extended to allow storing longer strings, and then executing stuff based on the string contents and stuff.  That’s for another day, I guess.

Or perhaps someone should just put support for stuff like this into … something.  X?  Or the window manager(s)?  Or both?  Anyway, that would be nicer.

Has anybody made something like that?

Slightly More Useful Fluttering

Some weeks back I wondered whether I could use Youtube as a screen saver.  It turned out that I could.

That wasn’t, strictly speaking, very useful, but now I had a small USB monitor sitting in the hall, so I might as well make it display something practical in addition to the music videos.

Hence: flit.

Currently it checks what temperature it’s outside my bedroom window and displays that at the top right there.  (Yes!  It’s that warm here in Oslo now!)

And then it downloads the weather forecast from Yr.no, picks out the precipitation data for the next 24 hours, and plots that as a line at the bottom.

Somewhat cryptic, but that’s part of the fun.

Technologies used: LaTeX to render the temperature data, gnuplot to render the precipitation line, and qiv to display the image with a transparent background on top of the mplayer window.  As one does.

Conspicuous Youtube Consumption

Stina Nordenstam rockin’ in the USB

I’ve been sleeping in even odder patterns than usual lately (I suspect that I’m coming down with microencephaly, SAD and “the hypo”), so I found myself staring at the stereo computer thinking that there should be movement.

I normally hate computer screens that have pulsing lights and stuff, but I wondered how much work it would be to automatically download music videos from Youtube for whatever was playing, and then just show the video.  The sound wouldn’t be synced up, of course, but it’d be a kinda… like…  spastic screen saver.

A screen saver that doesn’t save the screen or the CPU or the network or on electricity, and would probably get me banned from Youtube.

So I started typing, and here it is.

I had a spare USB-powered little screen, so I put the stuff on a small screen instead of using a big one.  I mean, that would be too fluttery.

It’s been in production for all of fifteen minutes now, so I have no idea whether I’m going to pull the plug on the “project” (and the USB monitor) or not.  I’m guessing I probably will.