newt
applicationsAs 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.
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).
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.