Keyboard device in Unix
The keyboard device itself is one of the entries in /dev/input
. You can locate keyboards and other input devices by their connection type (e.g. PS/2, USB, …) in /dev/input/by-path
. Obviously, you'll need to run as root to access the hardware directly, and you'll need to provide your own translation from raw bytes coming from the keyboard into things like key presses and key releases. This is probably not what you want.
If you're running a GUI application, the low-level method is to call XNextEvent
and other functions in the same family. Decoding input events isn't completely trivial, as it's up to applications to apply modifiers. A GUI framework (Motif, Gtk, Qt, …) would help you.
If you're running a terminal application, read from standard input or from /dev/tty
(/dev/tty
is always the terminal that your program is running on, even if standard input has been redirected). You'll want to put the terminal in raw mode. You'll get decoded character keys, and function keys mostly as escape sequences. Here, too, a library helps; the de facto standard is ncurses.
Mac low-level keyboard device corresponding to Linux /dev/input?
There is no such direct correspondence with a /dev/
node on macOS. HID events are (eventually) processed in the IOHIDSystem
class in the kernel and are transferred to user space into WindowServer via the IOHIDUserClient
. Applications can also directly access aspects of a HID device directly via the IOHIDLib, which uses IOHIDLibUserClient
to get kernel HID data.
macOS only uses /dev/
nodes for a handful of device types, notably block devices (diskXsY
, rdiskXsY
), serial ports, and the traditional UNIX virtual devices such as null
, zero
, random
, etc. There are also a few BSDisms, such as BPF. Almost everything else is handled only via IOKit.
Accessing Keys from Linux Input Device
Open the input device,
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <string.h>
#include <stdio.h>
static const char *const evval[3] = {
"RELEASED",
"PRESSED ",
"REPEATED"
};
int main(void)
{
const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
struct input_event ev;
ssize_t n;
int fd;
fd = open(dev, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
return EXIT_FAILURE;
}
and then read keyboard events from the device:
while (1) {
n = read(fd, &ev, sizeof ev);
if (n == (ssize_t)-1) {
if (errno == EINTR)
continue;
else
break;
} else
if (n != sizeof ev) {
errno = EIO;
break;
}
The above snippet breaks out from the loop if any error occurs, or if the userspace receives only a partial event structure (which should not happen, but might in some future/buggy kernels). You might wish to use a more robust read loop; I personally would be satisfied by replacing the last break
with continue
, so that partial event structures are ignored.
You can then examine the ev
event structure to see what occurred, and finish the program:
if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2)
printf("%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);
}
fflush(stdout);
fprintf(stderr, "%s.\n", strerror(errno));
return EXIT_FAILURE;
}
For a keypress,
ev.time
: time of the event (struct timeval
type)ev.type
:EV_KEY
ev.code
:KEY_*
, key identifier; see complete list in/usr/include/linux/input.h
ev.value
:0
if key release,1
if key press,2
if autorepeat keypress
See Documentation/input/input.txt in the Linux kernel sources for further details.
The named constants in /usr/include/linux/input.h
are quite stable, because it is a kernel-userspace interface, and the kernel developers try very hard to maintain compatibility. (That is, you can expect there to be new codes every now and then, but existing codes rarely change.)
Getting device input (mouse, keyboard ...) on LINUX
Under X Window system there is a concept of input-only windows, which is more or less parallel to that of message-only window under Windows.
Related Topics
Syntax Error Near Unexpected Token 'Do' When Run with Sudo
Sdl Configuration in Eclipse Ide
Batch Crop and Resize Images to Create Thumbnails
How to Set a Color Profile with Exiftool
Qxcbconnection: Could Not Connect to Display Aborted, When Installing Qt on Linux
Building Perf with Babeltrace (For Perf to Ctf Conversion)
Can't Add File to Git Repository But Can Change/Commit
Sending Command to Process Using /Proc
How to Deploy Files for a Remote Debug Launch in Eclipse Cdt
Linux Patch Ignoring Line Numbers
How to Give Password in Shell Script
Using Linux Virtual Mouse Driver
Naming Convention for Posix Flags
Bash Script Command to Wait Until Docker-Compose Process Has Finished Before Moving On