I'm working on an embedded Linux project where I will be developing a program that will run automatically on bootup and interact with the user via a character display and some sort of button array. If we go with a simple GPIO button array, I can easily write program that will look for keypresses on those GPIO lines. However, one of our thoughts was to use a USB number pad device instead for user input. My understanding is that those devices will present themselves to the OS as a USB keyboard. If go down this path, is there a way for my program to look for input on this USB keyboard from within Linux, keeping in mind that there is no virtual terminal or VGA display. When a USB keyboard is plugged in, is there an entity in '/dev' that appears that I can open a file descriptor for?
Linux – Is it possible for a daemon (i.e. background) process to look for key-presses from a USB keyboard
embeddedkeyboardlinuxusb
Related Solutions
Update 1
I believe the feature you are looking for is actually X Window multi-pointer.
From ArchLinux Multi-Pointer X Introduction:
Xorg servers starting from version 1.7 have a feature called "multi-pointer". Basically it allows to have multiple mouse cursors (each with its own keyboard focus) on the screen and control them with separate physical input devices. It can be used as a crude multiseat solution.
Check out following links
- Multi-Pointer X Wikipedia
- ArchLinux Multi-Pointer X
Original Answer
I saw various of those setup in the past (in term of years). So it is definitly doable. No need to re-write kenrel or x windows.
Doing a google search with linux multiple mouse pointers
, come up with multiple pages. Following is one of them
- linux: dual mice - multiple mice with multiple mouse pointers? A stackoverflow question asked and answer in 2010.
- multiple mouse / keyboard in linux which is a blog post.
Those are only 2 of many that come up.
If you search for linux multi-seat
, you will get links for one linux box supporting multiple KVM (keyboard+video+mouse). Following is one of them
So the technology is definitely already available, but how far you can go, or how they suit your need, you will have to spend sometime to research and experiment.
I found out that I need to send an EVIOCGRAB ioctl to the device, which grabs it for exclusive use.
Here's how to do it in Ruby:
#!/usr/bin/env ruby
BARCODE_SCANNER = "/dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd"
require 'rubygems'
require 'libdevinput'
require 'ffi'
require 'ffi/tools/const_generator'
# We need access to the file
DevInput.class_eval { attr_reader :dev }
# Look up value of EVIOCGRAB constant
cg = FFI::ConstGenerator.new('input') do |gen|
gen.include('linux/input.h')
gen.const(:EVIOCGRAB, '%u', '(unsigned)')
end
EVIOCGRAB = cg['EVIOCGRAB'].to_i
scanner = DevInput.new(BARCODE_SCANNER)
# Send EVIOCGRAB to scanner, which grabs it for exclusive use by our process
scanner.dev.ioctl(EVIOCGRAB, 1)
puts "Waiting for events..."
scanner.each do |event|
# Ignore everything except key press events
next unless event.type == 1 && event.value == 1
puts "Key: #{event.code_str}"
end
Note: You'll need to install the libdevinput
gem, ffi
, and Linux headers. If you are using a Linux version between 3.2.0
and 3.6.11
, you can replace the FFI::ConstGenerator
part with EVIOCGRAB = 1074021776
, and then you don't need ffi
or Linux headers.
Best Answer
Devices most likely get a file in
/dev/input/
namedeventN
where N is the various devices like mouse, keyboard, jack, power-buttons etc.should give you a hint.
Also look at:
Where
Sysfs
value is path under/sys
.You can test by e.g.
To implement use ioctl and check devices + monitor.
EDIT 2:
OK. I'm expanding on this answer based on the assumption
/dev/input/eventN
is used.One way could be:
At startup loop all
event
files found in/dev/input/
. Useioctl()
to request event bits:then check if
EV_KEY
-bit is set.IFF set then check for keys:
E.g. if number-keys are interesting, then check if bits for
KEY_0
-KEY9
andKEY_KP0
toKEY_KP9
.IFF keys found then start monitoring event file in thread.
Back to 1.
This way you should get to monitor all devices that meet the wanted criteria. You can't only check for
EV_KEY
as e.g. power-button will have this bit set, but it obviously won't haveKEY_A
etc. set.Have seen false positives for exotic keys, but for normal keys this should suffice. There is no direct harm in monitoring e.g. event file for power button or a jack, but you those won't emit events in question (aka. bad code).
More in detail below.
EDIT 1:
In regards to "Explain that last statement …". Going over in stackoverflow land here … but:
A quick and dirty sample in C. You'll have to implement various code to check that you actually get correct device, translate event type, code and value. Typically key-down, key-up, key-repeat, key-code, etc.
Haven't time, (and is too much here), to add the rest.
Check out
linux/input.h
, programs likedumpkeys
, kernel code etc. for mapping codes. E.g.dumpkeys -l
Anyhow:
Run as e.g.:
Code:
EDIT 2 (continued):
Note that if you look at
/proc/bus/input/devices
you have a letter at start of each line. HereB
means bit-map. That is for example:Each of those bits correspond to a property of the device. Which by bit-map means, 1 indicate a property is present, as defined in
linux/input.h
. :Have a look at
/drivers/input/input.{h,c}
in the kernel source tree. A lot of good code there. (E.g. the devices properties are produced by this function.)Each of these property maps can be attained by
ioctl
. For example, if you want to check what LED properties are available say:Look at definition of
struct input_dev
ininput.h
for howledbit
are defined.To check status for LED's say:
If bit 1 in
ledbit
are 1 then num-lock are lit. If bit 2 is 1 then caps lock is lit etc.input.h
has the various defines.Notes when it comes to event monitoring:
Pseudo-code for monitoring could be something in the direction of:
Some related documents:
Documentation/input/input.txt
, esp. note section 5.Documentation/input/event-codes.txt
, description of various events etc. Take note to what is mentioned under e.g.EV_SYN
aboutSYN_DROPPED
Documentation/input
... read up on the rest if you want.