Archive for October 2006

Improved introduction!

Josh suggested that my introductary page could use a little beefing up, and I agree. So there’s a new introduction with an extended example plus descriptions of each of the classes and how they fit together.

ruby libusb documentation

Yay documentation! I documented most of the methods is libusb but I’m not sure it really makes anything that much clearer if you don’t already have a fairly good understanding of the USB device specification. Anyways, take a look around and tell me what you think!

http://www.technofetish.net/repos/buffaloplay/ruby_libusb/doc/

World’s Most Getto Remote Control

As you might have guessed it would, my peculiar madness had me wandering ValueVillage this Saturday. I was looking for cheap USB keyboards to hack together into my ultimate VI keyboard. The keyboards were a lost cause as it turns out…only PS/2 stuff there…but I did discover something: the Toshiba LED Control Module PMD-C0188. It’s this chuky plastic box with two rows of buttons and a volume knob. If I had to guess I would say that it’s likely built to control some sort of fancy telephony app – but this is a guess.

Anyways, I took it home with me ($5) on the theory that it problably was a USB HID device that I could reprogram to control my little TV watching computer.

Altogther too long later, it finally works. Reverse engineering the button’s protocol turned out to be pretty easy (here’s the app that did it). That was the easy part. The annoying part was getting it to control VLC properly, and then getting it installed on my other box. For the most part, not problems you would be interested in.

Anyways, it works now and I’m going to watch a little anime in celebration. Here’s the code that did it.

VI inserting keyboard

Ever since I read the Raskin’s , I’ve been especially noticing what Raskin calls “mode errors” in VI. Mode errors happen when you have two different modes of operation and you accidently do a Mode A command in Mode B.

Raskin really hates this kind of error, partly because they interfere with the feedback that you need to become skilled. Every key combination needs to have a implict but because sometimes that involves doing something and sometimes it dosen’t, it’s difficult to train your fingers to do it automatically.

I can hear you VI users scoffing at me. I dunno if Raskin’s right about this, but every UI mode problem can be solved most ridiculously by adding more buttons…right?

So partly as a joke, partly to write a more interesting example of my USB library, and partly to see what it would be like, I’ve built a ruby script that let’s you use a USB be keyboard as “VI inserting keyboard”. Every text key presed in this keybord maps to “a[KEY][ESC][ESC]”. So if you use this keyboard in VI command mode you can enter whatever you want but stay in command mode. It strikes me that it might be saner to do the opposite – have an external keyboard permanently in command mode – perhaps that can be version 2.

Anyways, this works beautifuly and it only took me a couple of hours (mostly involved with finding the appropiate way to simulate X keys and map USB usages to X keysyms). Just figured you might be amused:

http://www.technofetish.net/repos/buffaloplay/vikeyboard/

If I’m really feeling motivated maybe I’ll glue two keyboards together tomorrow and try it out properly.

Working ruby HID listener example

So I haven’t been slacking off, even though things have been pretty quiet on the blog lately. What I’ve been doing is integrating both my HIDParser and libusb into ruby. This isn’t so much of a straight port like my evdev stuff…I’ve worked really hard to build interfaces hid most of the unecessary complexity from you but inferring everything from the USB descriptors. So for example here’s an application that listens for “F” presses on any appropiate USB keyboard:

require ‘libusb’

hid_device = USB::devices.select { |d| d.hid? }[0]
hid_interface = hid_device.interfaces { |i| i.hid? }[0]
hid_interface.detach_kernel
listener = USB::UsageListener.new(hid_interface)
usage = USB::Usage.find_usage_named(/Keyboard f/)
puts “listening for usage #{usage}”
listener.on_usage_value_change(usage) { |new_val| puts “New value: #{new_val}” }
listener.start_listening

Pretty simple, eh? In this case the application assumes that the first hid device on your system is capable of producing an F keypress (a slightly more complex example could check first).

Anyways, there’s a lot more that needs to be done in terms of fleshing out the interface – exposing greater amounts of the C/C++ layer and (perhaps) supporting a greater variety of USB transport mechanisms. But still, I’m pretty pleased with how simple the main case was able to get.

All the code is in my source control if you want to play around with it or look at it (the example is map_example). No documentation yet, but if that’s what’s holding people back I could be convinced to write it.

In theory it should be compatable with BSD and MacOS X though that has certianly never been tested. If you try it and you have trouble building or running the app, let me know I’m happy to help you figure it out.