New dialog functions

Ndialog is built around a collection of display objects, built into chains and fed to the MENU() function. It supports editable strings, check buttons, pushbuttons, menu lists, checklists, radio checklists, readonly text boxes, and readonly help (html subset) boxes.

To compile something with ndialog, you need to include the header file ndialog.h (if you also want to use the dialog compatability functions, you also need to include dialog.h header file.) When linking, you need to include libnd (libnd_g is the debugging version), and libcurses (or libncurses and libpanel)

The MENU() function and object chains


MENU(objchain,width,depth,title,prompt,flags) The core function of ndialog is MENU(), which takes an object chain, displays it, then lets the user type input into it. Object chains are built up from objects by the function ObjChain(), and are disposed of by the function deleteObjChain(). The appearance of a MENU form can be slightly modified by passing a combination of the following flags to it:

Make the window frame just a little bit fancier than normal.
Align the prompt to the left side of the form
Align the prompt to the right side of the form
print the prompt in a special error color (red, on color terminals) to indicate that something bad has happened to it.
MENU() has the following return codes:
Something went wrong; look at errno for details.
The menu processed okay and you can now use the results.
The user cancelled the menu.
The user used Esc to cancel the menu.
Error(fmt,…) The MENU() error function. You can override this with your own error function, if you so desire.
ObjChain(chain,obj) Add an object to an object chain. If the chain is NULL, create a new object chain containing just the object.
extractFromObjChain(chain,obj) extract the given object from the object chain, returning a pointer to the new object chain or NULL if something went wrong.
sortObjChain(chain) Sort the object chain according to the (x,y) coordinates of the object in the chain.
deleteObjChain(chain) Delete an object chain and all the objects contained in it.

Object operators

Objects are created by calling one of the object constructors listed below. Once created, you can do a few things with them:

copyObj(obj) This makes an exact copy of an object (including X and Y position, so it’s somewhat less than useful for application programmers.)
drawObj(obj,display) draw the object on the given display, which is a pointer to a magic object created by MENU() that tells drawObj how to display itself.

editObj(obj,display,event,byevent) Does editing on the given object. Event is a pointer to an gpm MEVENT record, and byevent is set if there is an even pending. The way ndialog events work is that when a mouse event happens inside editObj, editObj returns eEVENT so the caller can find out where the mouse even happened, find out which object will get the event, then call that object with byevent set to true.

editObj has the following return codes:

Nothing particular happened.
Something wicked happened. Errno may contain information about the fault.
The user cancelled out of this field.
The user pressed [Tab] to advance to the next field. The callback for this object will not be fired on a eTAB event, so it will need to be manually called when we’re finished with processing and are ready to continue.
The user pressed backtab to advance to the previous field. Otherwise like eTAB.
The user pressed [Return] to advance to the next field. The callback for this object is called on a eRETURN event.
A mouse or similar event happened and the caller needs to figure out what it was. As with eTAB and eBACKTAB, the callback function will not be called.
The user pressed Esc to cancel changes to this field.
The object wants the caller to refresh the screen.
The user is finished with input and wishes to exit this form.

[editObj()may, and probably will, calldrawObj()` to refresh fields while it is running.

deleteObj(obj) This disposes of the given object, (hopefully) returning all resources to the operating system.

Object constructors

Object constructers use some, or all, of the following arguments.

Place the object at (x,y) in the form. (x,y) is relative to the first line in the form after the prompt.
This is the width of the editable field. Any prefixes are not included in this width, nor are any fancy borders around the object.
This is the depth of the editable field. The title is not counted in this depth, nor are any fancy borders around the object.
If a prompt is given, it will be drawn immediately above the editable area in the object.
A prefix is another type of prompt. It goes immediately to the left of the editable field, unless it contains a |, in which case it will be split into a prefix and a suffix (eg: a prefix of foo|bar will display as fooeditablebar).
All objects support callback functions which are called when the user uses [Enter] to finish editing that object. Callback functions are passed a two void \* arguments – a pointer to the object and a pointer to display information, which can be passed to drawObj or editObj – and return an status flag (0 if the callback failed, 1 if the callback succeeded, or -1 if the callback succeeded and wants the caller to close up shop right now.
This argument, if given, is the name of a helpfile that gives help for this object. Helpfiles are an html subset and are processed by a Help object. Helpfiles can be pathnames or filenames, though it’s better to use setHelpRoot() to set the pathname instead of hardcoding it into the object.
newString(x,y,width,size,bfr,prompt,prefix,callback,help) Create a string object located at position (x,y) inside the window and that has a width column wide editing area.
newPWString(x,y,width,size,bfr,prompt,prefix,callback,help Creates a password string object, which is exactly like a normal string object except that input is not echoed.
newCheck(x,y,prompt,prefix,bfr,callback,help) Creates a check object. The state of the checkable item is in bfr[0], which is a character.
newButton(number,label,callback,help) Create a button object. Buttons are placed on a buttonbar at the bottom of the window, and are placed in order of their number argument (button #1 will be placed to the left of button #2, for example.) The text on the button is the label argument.
newOKbutton(number,label,callback,help) Create an OK button. An OK button is somewhat like a regular button, except that when it’s pushed, and if the callback approves, MENU() will immediately return with a code of MENU_OK.
newCancelButton(number,label,callback,help) Create a Cancel button. It’s exactly like an OK button, except that MENU() immediately returns with a code of MENU_CANCEL.
newText(x,y,width,height,size,prompt,prefix,bfr,callback,help) Create a Text object. This is a scrollable readonly field that contains size bytes of text in bfr.
newHelp(x,y,width,height,document,callback,help) Create a help text object. Document is a local html page (no file:, http:, url:, mailto:, or whatnot) which is formatted and displayed by this object. newHelp does not support a full html specification, but it supports enough of a subset to be able to read minimal pages legibly.

newList(x,y,width,height,nritems,items,prompt,prefix,flags,callback,help) Create a list object. Items is an array of ListItem’s (defined in ndialog.h as

typdef struct {
    char *id;
    char *item;
    char *help;
    char selected;
} ListItem;

where the id field is the libdialog key field, and help is context-sensitive help for this ListItem. The flags argument is a bitmap determining how the list will be displayed.

place a checkbox in front of each ListItem.
highlight selected items, and use arrow pointers to show the current item.
the list is a menu list; when you select an item, the list object will return control to the caller.
When displaying each ListItem, show both the item and the id. (This is now libdialog works).
Normally, a list will display with the first character in each item highlit, and you can type that character to jump to that item. If, for some reason, you don’t want to be able to do that, you can use this flag.
Select items from this list when the user presses the DEL key, not when they double-click or press return.
Always highlight the current item in a MENU_SELECTION list.
Fail if any of the items are too long to fit into the desired window.

You can find out what items are selected inside the callback function by using getObjList(void\* obj) to get a pointer to the array of ListItems, getObjListSize(void \*obj) to get the number of items in the list, then walking the list looking for selected items.

newRadioList(x,y,width,height,nritems,items,prompt,prefix,flags,callback,help) Creates a radiolist object, which is like a list object except that only one item can be selected at a time.
newMenu(x,y,width,height,nritems,items,prompt,prefix,flags,callback,help) Creates a menu object, which is like a list object except that it returns to the caller as soon as an item is selected.
newGauge(x,y,width,percent,prompt,prefix) Creates a gauge object, which is a readonly progress gauge, that’s displayed as percent filled.


Widgets are multipart display objects; they are manipulated exactly the same as other objects, but have wads of additional complexity tossed into them.


newListWidget(x, y, width, height, list, prompt, insert_callback, delete_callback, dummy, help); newEditableList(x, y, width, height, list, prompt, insert_callback, delete_callback, update_callback, help);

List widgets are made up of a string, a list, an ADD button, a DELETE button, and, optionally, a MODIFY button. They can be used for building lists of things, like, oh, dns servers, domains to search, and search order. The list they work on is a List Array object. You use the newListWidget or newEditableList functions to create a list widget.

The X and Y position of the widget on the form that displays it.
width, height
The width and the height of the list; this is NOT the width and the height of the entire widget. To compute that, add 12 to the width and 3 (4 if you give it a title) to the height.
The List Array that this widget works on.
A prompt string to go at the top of the widget.
insert_callback, delete_callback
These callbacks are called when you insert a new item into the list or delete an item from the list. They do not actually insert or delete items from the list; the list widget does that all by itself. All these callbacks do is validate the entry or deletion.
If this callback is nonzero, the list widget will have a MODIFY button that call it.
The helpfile.

List Arrays

A List Array is a way to encapsulate an array of ListItems. It is primarily used in widget sets, though you can use it to manage your own arrays. A List Array is called a LIA.

LIA functions

LIA newLIA(ListItem *list,int nrlist) Create a new LIA, initializing it from the given ListItem array. If you wish to create an empty LIA, pass 0 for the ListArray.
void deleteLIA(LIA obj) Delete a LIA.
int addToLIA(LIA obj,char *id,char *name,char *help) Add a ListItem to the LIA. We pass in the three useful fields of the listItem separately. Note that you must pass valid strings or 0 for the ListItem fields, because copies are made of these strings in the new row in LIA. addToLIA returns the number of rows in the list array.
int delFromLIA(LIA obj,int row) Delete the given row from the LIA. If the row cannot be deleted, it returns EOF, otherwise it returns the number of rows left in the LIA.
int LIAcount(LIA obj) Returns the number of rows in the LIA.
ListItem *LIAlist(LIA obj) Returns the ListItem array in the LIA.

Miscellaneous functions

setObjTitle(obj,title) Set the title for the given object
objTitle(obj) Get the title of the given object

setObjData(obj,…) Set the data for the object. The arguments depend on the object:

setObjData(obj,string, length);
Text [Help]
all others
setObjData(obj,data pointer);
setObjHelp(obj, help) Set the help for this object.
objDataPtr(obj) Return the data pointer for applicable objects (String, Check, Text)
objHelp(obj) Return the help for this object.
objSize(obj,&width,&depth) Return the area, including prompts, taken up by this object.
objAt(obj,&x,&y) Where is this object located in the window
ObjDataAt(obj,&x,&y,&width,&depth) Where is the data area of this object.
objType(obj) What type of object am I? I can be O_STRING, O_BUTTON, O_LIST, O_TEXT, or O_GAUGE
objId(obj) As above, except a string describing the object is returned.
isOKButton(obj) Am I an OK button?
isCancelButton(obj) Am I a CANCEL button?
getObjList(obj) Returns the array of ListItems that a list object contains.
getObjListSize(obj) Returns how many ListItemss that a list object contains.
getObjCursor(obj) return the current cursor position in an editable object
setObjCursor(obj,cursor) Set the current cursor position in an editable object
setWritable(obj) Make this object writable
setReadonly(obj) Make this object readonly
writable(obj) Tell us whether this object is writable
hideObj(obj) make this object invisible
unhideObj(obj) make this object visible
touchObj(obj) tell this object to redisplay itself the next time the window is redrawn
untouchObj(obj) tell this object not to redisplay itself the next time the window is redrawn.
touched(obj) Tell us if the object needs to be redrawn.
getHelpTopic(obj) Return the <TITLE> of a Help object
currentHtmlTag(obj) Return the currently selected html tag from a Help object
setHelpRoot(directory) Set the document root for helpfile lookups (qv: use_helpfile)
getHelpCursor(obj) Allocate a help cursor and return a pointer to it. Help cursors contain window positioning state and href linkages, so can’t be accessed by the conventional getObjCursor() and setObjCursor() methods.
setHelpCursor(obj,cursor) Set the cursor in a help object to the specified location. If it cannot do this, setHelpCursor will return 0, otherwise it will return 1

Example programs