1

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!

Haldean Brown
  • 12,411
  • 5
  • 43
  • 58

1 Answers1

1

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.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • 1
    Simple udev rule would persist /dev/input/event* permissions. I would rather create special group (say, "input") and then put something like `KERNEL=="event*", NAME="input/%k", MODE="640", GROUP="input"` to /etc/udev/rules.d/99-evdev.rules – barti_ddu Nov 29 '10 at 20:09
  • @barti: Ahh, I meant the permissions reverting as a good thing :-). But the idea of sandboxing the devices in a group is a good one. Unfortunately it seems all of these solutions are kind of gross for somebody that just wants to play the game (I would be wary of installing something that says it needs unfettered access to my keyboard device while the program is running, regardless of whether or not it's in the foreground or not). – Mark Peters Nov 29 '10 at 20:14
  • @Mark: Ok, I see Your point now (and I'm glad, I've provoked Your comment, anyway) :) Everything boils down to application type: I can't see any reason why the game should have access to system-wide keyboard events. On the other hand, tuning input access privileges looks less evil than setting setuid bit or running program as super user. But again, I can be missing something :) – barti_ddu Nov 29 '10 at 21:31
  • @bart_ddu: No, I totally agree. But I don't think either should be necessary. I don't know much about how that device input is filtered through the various layers; I would expect the problem is that it doesn't support a poll-based architecture as this would. Or maybe the problem is in requiring window focus; I'm not sure. Incidentally there *is* a keyboard controller that uses AWT instead of the native device, but I think there are some hoops to jump through with that. – Mark Peters Nov 29 '10 at 21:39
  • This was it. Thanks! It's a program that only I'll be using (it's a controller for a robotic helicopter), so the udev rule wins. – Haldean Brown Nov 29 '10 at 21:40
  • Great! I've added barti's info to the answer since he didn't post an answer himself. Thanks @barti, and feel free to edit if it's wrong/misrepresenting something you suggested. I don't have experience with udev rules and I don't have a Linux env handy. – Mark Peters Nov 29 '10 at 21:47
  • @haldean: This is precisely this "special case" :) – barti_ddu Nov 29 '10 at 21:55