This library implements a simple C++ API for using terminfo in linux terminals for those situations where using curses is inconvenient. UTIO can add colors to your text output, directly use some terminfo capabilities without going into fullscreen mode, and, when you do want fullscreen mode, it better integrates into modern event-driven designs.

How to build it

Download the package from https://github.com/msharov/utio/releases/latest. Make sure you have the necessary dependencies: C++11 compiler, such as gcc 4.6+, the uSTL library version 2.2+, and, if your distribution does not provide the terminfo database, it can be downloaded with the ncurses package.

    % ./configure && make && make install

./configure --help lists configuration options, like setting an installation path other than /usr/local. To use the library, include utio.h and link with -lutio. Look at the example programs in the text directory to start with something that is known to work.


"But I want this text to be red!" Is the simplest terminal capability you could ask for. If you have an application that just prints stuff out to the screen, like, say, a compiler, you might not necessarily want to use a fully featured windowing system just to make the error messages print out red. In curses you'd have to create a window and keep track of rotating the lines through the screen. CTerminfo answers this problem with a simple stream-based interface that lets you directly print terminal capabilities, taking care of all those little details, like having to set the bold attribute to get all 16 colors. Here's a simple example:

    CTerminfo ti;
    cout << ti.Color(red) << "Error: can't open file x" << endl;

The second (optional) argument to Color sets the background color. See EColor enum in ticonst.h for available color values. With color_Preserve value you can keep the fancy backgrounds provided by some graphical terminal emulators (ETerm). You can also draw simple stuff like lines (HLine, VLine) and boxes (Box), positioned where you want them (MoveTo), which is useful for making progress displays nicer than printing "23% complete" every few seconds. You can clear the screen (Clear) or just parts of it (Bar). You can get ASCII art from files and dump it on the screen (Image). In other words, do all those things that DOS programmers had forever; things that let them develop text editors, IDEs (Borland), file managers (Norton Commander), and many wonderful text mode games like zzt. CTerminfo also provides the ability to directly use terminal capabilities, if there is something you really need. You can get the terminfo-given values for booleans (GetBoolean), numbers (GetNumber), or strings (GetString). Take a look at ticonst.h for supported capability names.

There are a couple of things you need to remember when working with this class. First, because many terminfo capabilities are actually programs, some output strings must be built at runtime. CTerminfo uses an internal buffer to store the output before returning it. This allows all operations to work inline instead of requiring you to pass a buffer for each one. What this means to you is that you should not store pointers to the returned values. If you need to do it, copy it into your own string object. However, you can't use it again because of the second caveat, which is that the object keeps the current terminal state. So if you set the color to red and the set the color to red again, nothing will be written. This is a good thing, since it reduces the amount of control code the kernel has to parse, but it means you should not write your own control sequences. If you feel the need to force a write, you can reset the saved state with ResetState. I should also note that while this behaviour is not thread-safe, that it is so is irrelevant since you can't print to the terminal from different threads and expect consistent results. The terminal keeps state too and therefore must be used from one thread only.

The terminal description record is loaded from the terminfo database, usually located under /usr/share/terminfo. The database location may be overridden by setting TERMINFO environment variable to the correct location. If Load is called without an argument (which can give a specific terminal name), as in the example listing above, the terminal name is obtained from the TERM environment variable. If neither is set, the name defaults to "linux", which may or may not be correct. Loading errors are reported by throwing appropriate exceptions.


While CTerminfo is a decent interface for a simple, output-only application, a more sophisticated approach is usually desired for a truly interactive one. A well-designed, user friendly application would want to have more control over the screen contents, implementing some type of an event-driven windowing system. It would usually have a lot of stuff on the screen and so would want to optimize the output to redraw only the areas changed since the last update. This results in faster, more responsive application, since parsing the terminal control strings is a major bottleneck on the console. Furthermore, a windowing system always needs some type of a backbuffer into which each window can draw, to allow proper clipping and overlapping window support without making each window write its own code for them.

For all these purposes, this library provides the CGC class, roughly equivalent to the WINDOW structure in curses, and to the drawing context in most graphical UI environments. It contains a memory buffer into which all the drawing operations go. When you have finished writing into it, it can be blitted to the screen with the Image command in CTerminfo. The intended use, however is a triple-buffer rotating system that writes only differences between updates. Here is an example of how it might work:

    CTerminal ti;

    CGC gc,		// This is where the code draws.
	scr;		// This contains the current contents of the screen.

    // Make both the same size as the screen.
    gc.Resize (ti.Width(), ti.Height());
    scr.Resize (ti.Width(), ti.Height());

    while (inEventLoop) {
	Draw (gc);		// Draws everything that should be on the screen.
	gc.MakeDiffFrom (scr);	// Only the differences need to be written, so find them.
	// gc now has only new stuff, the rest is zeroed out, and isn't drawn.
	cout << ti.Image (0, 0, gc.Width(), gc.Height(), gc.Canvas().begin());
	screen.Image (gc);	// Now apply the same diff to the screen cache.
	gc.Image (screen);	// ... and copy it back for a fresh start.


An interactive application is worthless if you can't interact with it, so some code is invariably required to accept keystrokes from the user and to convert them to some usable values. If you have ever tried to read the keyboard on a Linux console, you know just how much of a pain it is. Instead of giving you a keycode for a key, it gives you escape sequences. Sequences that are different for every terminal. Modifier keys like Ctrl, Alt, or Shift, are intercepted by the kernel and translated into what it thinks are the right things to print on the screen. Yes, you can actually disable this translation and put the terminal in RAW mode, but woe be to you if anything happens to your application before it is able to unset it. The "cbreak" mode, used by curses and this library, is not too bad. If your application crashes, you can still type and restore normal operation. If you were in RAW mode though, only a hardware reboot will fix the computer, since you will not be able to type anything at all. Another downside of RAW mode is that the keyboard layout has to be manually loaded and interpreted, which would greatly increase the code size of this library. Thankfully, it is possible to run in semi-normal "cooked" mode and still interpret keycodes correctly. That is what CKeyboard is for.

    CTerminfo ti;
    CKeyboard kb;
    kb.Open (ti);	// Also places the terminal in UI-friendly mode.
    wchar_t key = 0;
    while (key != 'q') {
	CKeyboard::metastate_t meta;
	key = kb.GetKey (&meta);	// Synchronous call.
	// ... do whatever with key ...

Look in ticonst.h for EKeyDataValue enum of possible return codes. They are what will be returned instead of the escape sequences. Metakey state is in meta (which is an optional argument, in case you don't care about it). The above example demonstrates synchronous call usage. If you give GetKey false as a second argument, the call will return immediately with 0 if there is nothing to read. Then you can continue with your idle loop or do a select call on whatever file descriptors you are currently watching.

It is important to allow CKeyboard to call its destructor (or to manually call LeaveUIMode) before exiting. If it fails to do so, the keyboard remains in the UI state and the shell will not be usable. There will be no echo, no cursor, and no scrollback. (You can manually fix it with "stty sane" and "echo ^v ESC c") This cleanup problem is common to all UI environments, be it curses, console, the framebuffer, or X. Crashing the UI environment without cleanup is a very bad idea. It's also pretty bad for your objects in general, possibly resulting in leaking resources, memory, IPC resources, etc. Most object oriented UI frameworks take care of this for you in some way. Some require an application object, which is guaranteed destructed on exit; you can see an example implementation of this approach in the test directory. Some just register atexit() functions to clean up anything that really needs to be cleaned up. And then there are those who just assume nothing bad will ever happen and that the user knows how to reboot. Try not to fall into the last category.

What if it doesn't work?

Problems should be reported using Github project trackers reachable from the library project page.