I'm writing a program that needs to poll keyboard keys at specific times, and rather than going through the effort of writing my own event-driven keyboard polling class, I thought I'd use JInput's built-in Keyboard class.
It works perfectly when I run my program as root (I'm running on Ubuntu 10.10) but it doesn't even detect the fact that the keyboard exists when run as a normal user. I get the following error output:
Nov 29, 2010 2:08:50 PM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Loading: net.java.games.input.LinuxEnvironmentPlugin
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event11): Failed to open device /dev/input/event11 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event10): Failed to open device /dev/input/event10 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event9): Failed to open device /dev/input/event9 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event8): Failed to open device /dev/input/event8 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event7): Failed to open device /dev/input/event7 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event6): Failed to open device /dev/input/event6 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event5): Failed to open device /dev/input/event5 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event4): Failed to open device /dev/input/event4 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event3): Failed to open device /dev/input/event3 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event2): Failed to open device /dev/input/event2 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event1): Failed to open device /dev/input/event1 (13)
Nov 29, 2010 2:08:50 PM net.java.games.input.ControllerEnvironment log
INFO: Failed to open device (/dev/input/event0): Failed to open device /dev/input/event0 (13)
Does anyone have any experience using keyboards in JInput or any ideas for how to work around this so I don't have to run as root? Thanks!
Instead of running the program as root, you can also do
sudo chmod a+r /dev/input/event5
(Or whichever device points to your keyboard) It's up to you to decide which is more secure for your purposes, though. I think, but am not sure, that the permissions will revert after a restart.
I was never able to get JInput's keyboard adapter to work in Ubuntu without running the application as root or doing the above. Probably not an answer you wanted, but it will at least tell you you're not alone.
The obvious reason for why the device can't be read by just anyone is so that an unprivileged program (i.e. keylogger) can't just listen to all input coming from the keyboard at any given time. I think the various windowing systems run in a privileged mode and then control access to the keyboard data to user programs. If JInput went through that layer you probably wouldn't need special privileges.
Edit
Since it seemed to work for the OP, I'll include barti_ddu's note here. As an alternative to manually changing the permissions on the keyboard device as I have noted above, you can also set a udev rule such that these permissions are set automatically. Notably, you could use it to set the group for the device (say "input") and then run the program accordingly.
It would involve adding something like this to /etc/udev/rules.d/99-evdev.rules
:
KERNEL=="event*", NAME="input/%k", MODE="640", GROUP="input"
Warning: untested.