Writing Programs Using `newt`
Prev |  | Next

# 2. Basic `Newt` Functions

While most `newt` functions are concerned with widgets or groups of widgets (called grids and forms), some parts of the `newt` API deal with more global issues, such as initializing `newt` or writing to the root window.

## 2.1. Starting and Ending `newt` Services

There are three functions which nearly every `newt` application use. The first two are used to initialize the system.

    int newtInit(void);
    void newtCls(void);

`newtInit()` should be the first function called by every `newt` program. It initializes internal data structures and places the terminal in raw mode. Most applications invoke `newtCls()` immediately after `newtInit()`, which causes the screen to be cleared. It's not necessary to call `newtCls()` to use any of `newt`'s features, but doing so will normally give a much neater appearance. When a `newt` program is ready to exit, it should call `newtFinished()`.

    int newtFinished(void);

`newtFinished()` restores the terminal to its appearance when `newtInit()` was called (if possible -- on some terminals the cursor will be moved to the bottom, but it won't be possible to remember the original terminal contents) and places the terminal in its original input state. If this function isn't called, the terminal will probably need to be reset with the `reset` command before it can be used easily.

## 2.2. Handling Keyboard Input

Normally, `newt` programs don't read input directly from the user. Instead, they let `newt` read the input and hand it to the program in a semi-digested form. `Newt` does provide a couple of simple functions which give programs (a bit of) control over the terminal.

    void newtWaitForKey(void);
    void newtClearKeyBuffer(void);

The first of these, `newtWaitForKey()`, doesn't return until a key has been pressed. The keystroke is then ignored. If a key is already in the terminal's buffer, `newtWaitForKey()` discards a keystroke and returns immediately. `newtClearKeyBuffer()` discards the contents of the terminal's input buffer without waiting for additional input.

## 2.3. Drawing on the Root Window

The background of the terminal's display (the part without any windows covering it) is known as the root window (it's the parent of all windows, just like the system's root directory is the parent of all subdirectories). Normally, applications don't use the root window, instead drawing all of their text inside of windows (`newt` doesn't require this though -- widgets may be placed directly on the root window without difficulty). It is often desirable to display some text, such as a program's name or copyright information, on the root window, however. `Newt` provides two ways of displaying text on the root window. These functions may be called at any time. They are the only `newt` functions which are meant to write outside of the current window.

    void newtDrawRootText(int left, int top, const char * text);

This function is straightforward. It displays the string `text` at the position indicated. If either the `left` or `top` is negative, the position is measured from the opposite side of the screen. The final measurement will seem to be off by one though. For example, a `top` of -1 indicates the last line on the screen, and one of -2 is the line above that. As it's common to use the last line on the screen to display help information, `newt` includes special support for doing exactly that. The last line on the display is known as the help line, and is treated as a stack. As the value of the help line normally relates to the window currently displayed, using the same structure for window order and the help line is very natural. Two functions are provided to manipulate the help line.

    void newtPushHelpLine(const char * text);
    void newtPopHelpLine(void);

The first function, `newtPushHelpLine()`, saves the current help line on a stack (which is independent of the window stack) and displays the new line. If `text` is `NULL`, `newt`'s default help line is displayed (which provides basic instructions on using `newt`). If `text` is a string of length 0, the help line is cleared. For all other values of `text`, the passed string is displayed at the bottom, left-hand corner of the display. The space between the end of the displayed string the the right-hand edge of the terminal is cleared. `newtPopHelpLine()` replaces the current help line with the one it replaced. It's important not to call tt/newtPopHelpLine()/ more then `newtPushHelpLine()`! `Suspending Newt Applications` By default, `newt` programs cannot be suspended by the user (compare this to most Unix programs which can be suspended by pressing the suspend key (normally `^Z`). Instead, programs can specify a callback function which gets invoked when the user presses the suspend key.

    typedef void (*newtSuspendCallback)(void);

    void newtSetSuspendCallback(newtSuspendCallback cb);

The suspend function neither expects nor returns any value, and can do whatever it likes to when it is invoked. If no suspend callback is registered, the suspend keystroke is ignored. If the application should suspend and continue like most user applications, the suspend callback needs two other `newt` functions.

    void newtSuspend(void);
    void newtResume(void);

`newtSuspend()` tells `newt` to return the terminal to its initial state. Once this is done, the application can suspend itself (by sending itself a `SIGTSTP`, fork a child program, or do whatever else it likes. When it wants to resume using the `newt` interface, it must call `newtResume` before doing so. Note that suspend callbacks are not signal handlers. When `newtInit()` takes over the terminal, it disables the part of the terminal interface which sends the suspend signal. Instead, if `newt` sees the suspend keystroke during normal input processing, it immediately calls the suspend callback if one has been set. This means that suspending newt applications is not asynchronous.

## 2.4. Refreshing the Screen

To increase performance, S-Lang only updates the display when it needs to, not when the program tells S-Lang to write to the terminal. ``When it needs to'' is implemented as ``right before the we wait for the user to press a key''. While this allows for optimized screen displays most of the time, this optimization makes things difficult for programs which want to display progress messages without forcing the user to input characters. Applications can force S-Lang to immediately update modified portions of the screen by calling `newtRefresh`.

1. The program wants to display a progress message, without forcing for the user to enter any characters.

2. A misfeature of the program causes part of the screen to be corrupted. Ideally, the program would be fixed, but that may not always be practical.

## 2.5. Other Miscellaneous Functions

As always, some function defy characterization. Two of `newt`'s general function fit this oddball category.

    void newtBell(void);
    void newtGetScreenSize(int * cols, int * rows);

The first sends a beep to the terminal. Depending on the terminal's settings, this been may or may not be audible. The second function, `newtGetScreenSize()`, fills in the passed pointers with the current size of the terminal.

## 2.6. Basic `newt` Example

To help illustrate the functions presented in this section here is a short sample `newt` program which uses many of them. While it doesn't do anything interesting, it does show the basic structure of `newt` programs.

    #include <newt.h>
    #include <stdlib.h>

    int main(void) {
        newtInit();
        newtCls();

        newtDrawRootText(0, 0, "Some root text");
        newtDrawRootText(-25, -2, "Root text in the other corner");

        newtPushHelpLine(NULL);
        newtRefresh();
        sleep(1);

        newtPushHelpLine("A help line");
        newtRefresh();
        sleep(1);

        newtPopHelpLine();
        newtRefresh();
        sleep(1);

        newtFinished();
    }

Prev | Home | Next
Writing Programs Using `newt` |  | Windows