# Writing Programs Using `newt`

### Erik Troan, <ewt@redhat.com>

v0.31, 2003-Jan-06

The `newt` windowing system is a terminal-based window and widget library designed for writing applications with a simple, but user-friendly, interface. While `newt` is not intended to provide the rich feature set advanced applications may require, it has proven to be flexible enough for a wide range of applications (most notably, Red Hat's installation process). This tutorial explains the design philosophy behind `newt` and how to use `newt` from your programs.

# 1. Introduction

`Newt` has a definite design philosophy behind it, and knowing that design makes it significantly easier to craft robust `newt` applications. This tutorial documents `newt` 0.30 --- older versions of `newt` had annoying inconsistencies in it (which writing this tutorial pointed out), which were removed while this tutorial was written. The latest version of `newt` is always available from Red Hat.

## 1.1. Background

`Newt` was originally designed for use in the install code for Red Hat Linux. As this install code runs in an environment with limited resources (most importantly limited filesystem space), `newt`'s size was immediately an issue. To help minimize its size, the following design decisions were made early in its implementation:

- `newt` does not use an event-driven architecture.

- `newt` is written in C, not C++. While there has been interest in constructing C++ wrapper classes around the `newt` API, nothing has yet come of those ideas.

- Windows must be created and destroyed as a stack (in other words, all `newt` windows behave as modal dialogs). This is probably the greatest functionality restriction of `newt`.

- The tty keyboard is the only supported input device.

- Many behaviours, such as widget traversal order, are difficult or impossible to change.

While `newt` provides a complete API, it does not handle the low-level screen drawing itself. Instead, `newt` is layered on top of the screen management capabilities of John E. Davis's S-Lang library.

## 1.2. Designing `newt` applications

As `newt` is not event driven and forces modal windows (forcing window order to behave like a stack), newt applications tend to look quite like other text-mode programs. It is quite straightforward to convert a command line program which uses simple user prompts into a `newt` application. Some of the programs run as part of the Red Hat installation process (such as `Xconfigurator` and `mouseconfig`) were originally written as simple terminal mode programs which used line-oriented menus to get input from the user and were later converted into `newt` applications (through a process affectionately known as newtering). Such a conversion does not require changes to the control flow of most applications. Programming `newt` is dramatically different from writing programs for most other windowing systems as `newt`'s API is not event driven. This means that `newt` applications look dramatically different from programs written for event-driven architectures such as Motif, `gtk`, or even Borland's old TurboVision libraries. When you're designing your `newt` program, keep this differentiation in mind. As long as you plan your application to call a function to get input and then continue (rather then having your program called when input is ready), programming with the newt libraries should be simple.

## 1.3. Components

Displayable items in `newt` are known as components, which are analogous to the widgets provided by most Unix widget sets. There are two main types of components in `newt`, forms and everything else. Forms logically group components into functional sets. When an application is ready to get input from a user, it ``runs a form'', which makes the form active and lets the user enter information into the components the form contains. A form may contain any other component, including other forms. Using subforms in this manner lets the application change the details of how the user tabs between components on the form, scroll regions of the screen, and control background colors for portions of windows. Every component is of type `newtComponent`, which is an opaque type. It's guaranteed to be a pointer though, which lets applications move it through void pointers if the need arises. Variables of type `newtComponent` should never be directly manipulated -- they should only be passed to `newt` functions. As `newtComponent` variables are pointers, remember that they are always passed by value -- if you pass a `newtComponent` to a function which manipulates it, that component is manipulated everywhere, not just inside of that function (which is nearly always the behaviour you want).

## 1.4. Conventions

`Newt` uses a number of conventions to make it easier for programmers to use.

- All functions which manipulate data structures take the data structure being modified as their first parameter. For example, all of the functions which manipulate forms expect the `newtComponent` for that form to be the first parameter.

- As `newt` is loosely typed (forcing all of the components into a single variable makes coding easier, but nullifies the value of type checking), `newt` functions include the name of the type they are manipulating. An example of this is `newtFormAddComponent()`, which adds a component to a form. Note that the first parameter to this function is a form, as the name would suggest.

- When screen coordinates are passed into a function, the x location precedes the y location. To help keep this clear, we'll use the words ``left'' and ``top'' to describe those indicators (with left corresponding to the x position).

- When box sizes are passed, the horizontal width precedes the vertical width.

- When both a screen location and a box size are being passed, the screen location precedes the box size.

- When any component other then a form is created, the first two parameters are always the (left, right) location.

- Many functions take a set of flags as the final parameter. These flags may be logically ORed together to pass more then one flag at a time.

- `Newt` uses callback functions to convey certain events to the application. While callbacks differ slightly in their parameters, most of them allow the application to specify an arbitrary argument to be passed to the callback when the callback is invoked. This argument is always a `void *`, which allows the application great flexibility.

|  | Next
|  | Basic `Newt` Functions