Version 0.1a, December 2020
console-idle
is a screen-saver manager for the Linux framebuffer console.
It is a simple utility that provides screen-saver or
standby functionality for Linux framebuffer consoles. Normally,
when a framebuffer console is in use, only screen blanking is possible,
and even that is not enabled by default on modern systems.
Iconsole-idle
allows any custom program, that outputs
to the framebuffer, to run when the system appears to be idle.
This can be a screen-saver, or a program that displays
general information, or anything else.
console-idle
has a narrow range of applications. It is intended
for minimal and embedded Linux systems that offer a terminal
interface. It doesn't work with X -- but there's no need for it,
because X has its own screen-saver implementation.
console-idle
runs quietly in the background, and monitors selected
input devices for activity. After a certain period of inactivity, it
starts a user-selected screen-saver program, which is expected to
draw the screen.
When further activity is detected, console-idle
restores the
framebuffer and sends a TERM signal to the screen-saver program it launched.
console-idle
should be compatible with terminal-mode programs
that use curses
and similar frameworks to produce complex
layout.
console-idle
has no dependencies, and requires no specific
installation. All configuration is through command-line switches.
console-idle
It does not read or write any files, and can be
used in a completely read-only Linux system. Its CPU usage is
normally unmeasurable.
I wrote console-idle
to use with a console-mode, multi-room audio
controller system based on Raspberry Pi. It works with the
various framebuffer-based graphics programs in my Github repository.
console-idle [options] -- command args...
Note the double-dash (--) between the arguments to console-idle
and
the command to be executed. Without this, arguments to the command will
be interpreted as arguments to console-idle
.
console-idle \\
--dev /dev/input/event0 --dev=/dev/input/mice \\
-timeout 60 \\
-- jpegtofb --sleep 60 --landscape \\
--randomize /photos/*.jpg
Invoke jpegtofb
(https://github.com/kevinboone/jpegtofb)
to provide a slideshow screen-saver whenever the
selected input devices have been idle for more than two minutes.
In this example, /dev/input/mice
is the standard mouse device, and
/dev/input/event0
is the keyboard. There's no automated way for
console-idle
to determine which devices to monitor -- see
discussion of this point below.
The usual:
$ make
$ sudo make install
console-idle
has no external dependencies.
-d,--device=/dev/..
An input device such as /dev/input/event1
or /dev/input/mice
. Many
devices can be watched at the same time. The utility generates no
discernable CPU load, however many devices are monitored.
-D,--debug
In debug mode, console-idle
can be run in the foreground in
a terminal session, and verbose logging can be enabled. Logging is
to stderr
. Otherwise,
console-idle
detaches from any controlling terminal, and
logs to the system logger.
-f,--fbdev
Framebuffer device; defaults to /dev/fb0
. console-idle
needs
read and write access to the framebuffer, so it can restore the original
screen contents when activity is detected. console-idle
saves and
restores the framebuffer so that the screen-saver program it launches
does not have to be able to.
-l,--log-level=N
A number representing the verbosity of logging, from 0 (fatal errors
only) to 4 (function call tracing). Since console-idle
is not
designed to be run in a user session, low-level (severe) messages are
written to the system log, unless running in debug mode. Consequently,
setting a log level greater than 2 has no effect except in debug
mode.
-t,--timeout=seconds
The time in seconds that console-idle will wait for input activity, before launching the screen-saver program. The default is 120 seconds, or two minutes.
console-idle
requires a huge number of elevated privileges --
on the terminal device, framebuffer device, and input devices.
It would be very difficult to make it run other than as root
.
Most likely the same is true of any screen-saver program it runs,
so 'console-idle' does not attempt to change its user ID when
launching the screen-saver program.
To run a screen-saver program as an unprivileged user, have
console-idle
run a shell that uses su
to switch
users.
Typical devices to monitor include those for the mouse,
keyboard, and touchscreen. These devices
usually have entries in /dev/input
that can be polled without stealing
data from other applications. However, there's no systematic way that
the utility can work out which devices to monitor -- this may require
some trial-and-error. Doing hexdump /dev/input/eventNN
will usually
reveal which devices respond to which kinds of input. It's possible,
and probably necessary, to monitor a number of different devices.
In the end, console-idle
is a hack. Unlike X, the console has no
API that an application can tap into to coordinate screen-saver
operations. The program does te best it can, but there are
significant limitations.
console-idle
has no way to know whether the screen-saver
program it is told to launch will work, or even exist. It is the
user's responsibility to ensure that the path of the screen-saver
program, and any arguments it takes, are correct.
The screen-saver program launched by console-idle
must run
in the foreground, and be capable of being stopped by the receipt of
a TERM
signal.
The screen-saver program must produce no further output to the
framebuffer after the TERM
signal is received. It should shut
down reasonably quickly -- certainly before the system becomes
idle again. However, so long as it doesn't produce output after being
signalled, it doesn't have to stop immediately.
The screen-saver program need not save or restore the screen contents
console-idle
will do this. However, console-idle
does not clear the screen when it launches a program -- it assumes
that the screen-saver program will draw the whole screen (or, at least,
blank the unused screen areas).
console-idle
uses an ioctl()
call to disable text output from
the Linux console when it launches the screen-saver program. However,
it can't prevent output from another program that writes directly to the
framebuffer. Outside of the X environment, most graphical programs
do write directly to the framebuffer, although console-mode
programs rarely do. The screen-saver program launched
by console-idle
will try to overwrite whatever happens to be on the
screen, however it was generated. However, if a program is running
that continues to write to the framebuffer in the absence of user
input, then there will be two programs competing for the framebuffer.
The results are likely to be unsightly, at best.
If a console program does produce
complex terminal output in the absence of user input, there's
always an outside chance
that the screen-saver will switch on or off mid-way through a
sequence of control characters. Because
console-idle
disables terminal character output when the
screen-saver is running, multi-character sequences could potentially
be truncated.
The results are likely to be decidedly
odd if this happens, but it can only happen when running a program that
produces output without user input.
When console-idle
shuts down -- which it will only do when
sent a signal -- it tries to leave the screen as it found it.
That is, it tries to restore the screen contents if a screen-saver program
is running, and to enable the console cursor if it disabled it.
This process might take a second or so.
console-idle
can only monitor input devices that work with the
poll()
system call, and which can have their activity status
reset by reading them. In practice, all Linux raw
input devices with entries in /dev/input
are of this type.
Terminal devices like /dev/tty
are not.
console-idle
can't "remove" keyboard or mouse input from the input
buffer -- it monitors raw devices, not any particular terminal's
input buffer. So whatever keystroke or mouse movement caused the
screen-saver to quit will become available to a program that is waiting
for input.
console-idle
only works with 24 bits-per-pixel, linear framebuffers.
The great majority of Linux framebuffers are of this type, but not
all of them.
It should go without saying that console-idle
will be neither
functional, nor remotely necessary, with an X desktop.
console-idle
uses execvp()
to launch the screen-saver
program. This means that the specified program will be searched
for in the usual
locations and the directories specified by $PATH
. The screen-saver
program will have the same environment as the console-idle
program.
To disable output from the console terminal, console-idle
uses
an ioctl() call to set the terminal to "graphics" mode. "Ordinary"
text output is completely ignored in "graphics" mode, and the regular
console cursor is hidden.
To restore the screen contents after shutting down the screen-saver
program, console-idle
stores the original framebuffer contents in
RAM. With a large display, this could use a significant amount of
memory. However, console-idle
is designed to be usable on embedded
Linux systems with a read-only filesystem, so storage in a file
might be impossible. On a Raspberry Pi with an 800x480 display, for example,
storing the screen contents uses just under 1Mb of RAM.
console-idle
can be started at any point in the initialization of
the system after the /dev/
filesystem is available. Because of the
wide variety of different embedded system configurations, it's difficult
to give more specific installation advice than this.
Because there's only so many hours in the day, console-idle
uses
a general-purpose library that I use in most of my utilities. There's
far more code in the source bundle than is actually required -- that's
the way of libraries. The Makefile
enables segment garbage collection,
so that unused library functions are not included in the final executable,
which should be about 30kB in size.
console-idle
is copyright (c)2020 Kevin Boone, and distributed under the
terms of the GNU Public Licence, version 3.0. Essentially that means
you may use the software however you wish, so long as the source
code continues to be made available, and the original author is
acknowledged. There is no warranty of any kind.
Framebuffer memory
0.1a December 2020
First working release