Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I capture keyboard events and use a monitor as a text-display on Linux?

I have a server running in multi-user mode that is connected to a keyboard and a monitor. On a separate computer, I would like to SSH to the server and run a program that captures input from the keyboard and prints text to the monitor. The keyboard and monitor will never be used for any other purpose.

Right now, when the server boots, a (text) login screen is displayed on the monitor. I know that I can write to the corresponding /dev/tty device. However, the keyboard also writes to the same place.

How can I capture keyboard events and use a monitor as a text-display on Linux?

I may be missing some of the basics around hardware interfacing on Linux. What do I need to know?

Running out of bounty time - If someone wants to flesh this out further I'll award accordingly:

I did the following to prevent any login programs from starting:

systemctl mask serial-getty@ttyO0
systemctl mask systemd-logind
systemctl mask getty@tty1

Then I am running my program when required with:

openvt -c 1 -f /path/to/my/program

This would be a fully satisfying solution, except for that pesky -f. What is running on tty1? Is there anything I can do to stop it? Should I stop it?

Notably, this solution does meet all of my needs -- As far as I understand it, I am taking over the tty and thus get access to its stdin (receiving output from keyboard) and stdout (printing to monitor).

like image 450
ToBeReplaced Avatar asked Jun 03 '15 17:06

ToBeReplaced


1 Answers

If you are willing to go to low level programming you don't have to handle stdin or stdout. Just talk to the keyboard device and the console device directly.

Take a look at the source code of input-events from input-utils. It uses raw data to read keyboard, mouse or any other input device.

To avoid the default processing of the keyboard it uses the grab mode (-g in the CLI), that translates to a:

ioctl(fd,EVIOCGRAB,1)

in the device file descriptor. Reading raw events from /dev/input/event* is more or less straightforward: #include <linux/input.h>, do the grab thing, and then read struct input_event structures from the device.

To write to the console, if you don't want to mess with the TTY madness, and now that you are in low level mode, you may prefer to write directly to /dev/vcs, or /dev/vcsa for color (a for attribute) output.

Basically the vcs has one byte per screen cell that contains the code of the character shown. In vcs there are two bytes: the character and the attributes. See man vcs for details.

like image 54
rodrigo Avatar answered Oct 16 '22 09:10

rodrigo