Eric Wilhelm
and 1 contributors


Linux::USBKeyboard - access devices pretending to be qwerty keyboards


Use `lsusb` to discover the vendor id, product id, busnum, and/or devnum. See also `udevinfo` or /sys/bus/usb/devices/* for more advanced info.


This module gives you access to usb barcode scanners, magstripe readers, numpads and other "pretend I'm a keyboard" hardware.

It bypasses the keyboard driver so that your dvorak or international keymap won't get in the way. It also allows you to distinguish one device from another, run as a daemon (not requiring X/console focus), and other good things.


This module assumes that you want the device to use a qwerty keymap. In the case of magstripes and barcode scanners, this is almost definitely the case. A tenkey pad won't matter. For some kind of secondary usermode keyboard (e.g. gaming, etc) maybe you actually want to be able to apply a keymap?

I'm not sure how to let the main hid driver have the device back. You have to unplug it and plug it back in or run `libhid-detach-device`.

Patches welcome.


You'll need a fairly modern Linux,, and libusb.

  cpan Inline
  aptitude install libusb-dev

You should setup udev to give the device `plugdev` group permissions or whatever (rather than developing perl code as root.) One way to do this would be to add the following to /etc/udev/permissions.rules:

  SUBSYSTEM=="usb_device", GROUP="plugdev"



  my $kb = Linux::USBKeyboard->new($vendor_id, $product_id);

  my $kb = Linux::USBKeyboard->new(busnum => 1, devnum => 2);

  my $kb = Linux::USBKeyboard->new(vendor => $vendor_id, busnum => 1);


You may pass the vendor and product IDs as raw parameters, or you may pass any combination of vendor, product, busnum, devnum, and/or iface as named parameters. At least one parameter other than iface must be specified. iface is the interface to claim on the device, and it defaults to 0. No other parameters have defaults.


Hex numbers passed as strings must include the leading '0x', otherwise they are assumed to be integers.

Arguments may also be a hash (vendor => $v, product => $p) or (busnum => $b, $devnum => $d) or any mixture thereof.

  my ($hash) = $class->_check_args(@_);


Get a filehandle to a forked process.

  my $fh = Linux::USBKeyboard->open(@spec);

The @spec has the same format as in new(). The filehandle is an object from a subclass of IO::Handle. It has the method $fh->pid if you need the process id. The subprocess will be automatically killed by the object's destructor.

I've tested reading with readline($fh) and getc($fh) (both of which will block.) See examples/ for an example of IO::Select non-blocking multi-device usage.


Similar to open(), but returns one keypress (plus "bucky bits") per line, with single-character names where applicable and long names for all of the function keys, direction keys, enter, space, backspace, numpad, &c.

  my $fh = Linux::USBKeyboard->open_keys(@spec);

The "bucky bits" ('shift', 'ctrl', 'alt', and 'super') will be appended after the keyname and joined with spaces. Both the short name (e.g. 'alt') and a form preceded by 'right_' and/or 'left_' will be present. Mapping these into a hash allows you to ignore (or not) whether the shift key was pressed on the right or left of the keyboard.

  my ($k, @bits) = split(/ /, $line);
  my %bucky = map({$_ => 1} @bits);

For now, the character keys will simply be shifted as per open()

For key names, see the source code of this module. The names are common abbreviations in lowercase except for F1-F12.



Returns the character (with shift bit applied) for a pressed key.

  print $k->char;

Note that this returns the empty string for any keys which are non-normal characters (e.g. backspace, esc, F1.) The 'Enter' key is returned as "\n".


Get the raw keycode. This allows access to things like numlock, but also returns keyup events (0). Returns -1 if there was no event before the timeout.

Note that this can only detect the press of a single key. The device does send extra data if two keys are pressed at the same time (e.g. "a" and "x"), but at some point the code becomes ambiguous anyway because keyboards do not contain 105 wires (and every device is different.)

  my ($code, $shiftbits) = $kb->keycode;


Eric Wilhelm @ <ewilhelm at cpan dot org>


If you found this module on CPAN, please report any bugs or feature requests through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

If you pulled this development version from my /svn/, please contact me directly.


Copyright (C) 2007 Eric L. Wilhelm, All Rights Reserved.


Absolutely, positively NO WARRANTY, neither express or implied, is offered with this software. You use this software at your own risk. In case of loss, no person or entity owes you anything whatsoever. You have been warned.


This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.