Keyboard Device in Unix

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



Leave a reply



Submit