(3)

NAME
XfwfAlert

DESCRIPTION
The XfwfAlert widget is a pop-up dialog box with three parts: an icon in the top left corner, a text area, and a row of buttons along the bottom. Usually the alert widget is used for error messages, warnings and other kinds of informational messages. The icon indicates the type of message: (fatal) error, warning, other message, request for confirmation, etc. There are some built-in icons for these types. Most alerts will have one or two buttons, e.g., OK and CANCEL. An alert widget can be created in the usual way for shells, with XtVaCreatePopup and similar routines, but a much more convenient way is a call to XfwfDialog. XfwfDialog creates a temporary alert widget and waits for the user to acknowledge it by clicking one of the buttons. The function returns the number of the button that was clicked. An alert is made up of XfwfBoard(3X11), XfwfIcon(3X11), Xfwflabel(3X11) and XfwfButton(3X11) widgets. The label widget will be set to the minimum size that will show the full message. The alert widget will be as small as possible to show all its children.

  Public variables
XfwfAlert
Name | Class | Type | Default
XtNicon | XtCIcon | Icon * | "NONE"
XtNmessage | XtCMessage | String | NULL
XtNbuttons | XtCButtons | String | NULL
XtNlastChoice | XtCLastChoice | Int | 0
XtNcallback | XtCCallback | Callback | NULL

XtNicon
    The icon is of type Icon (see XfwfIcon(3X11)). The converter can load images from file and it knows about 6 built-in icons: "FATAL", "ERROR", "WARNING", "QUESTION", "INFO" and "NONE". The NONE icon is an invisible (i.e., transparent) image of the same size as the others.
    Icon * icon = <String>"NONE"

XtNmessage
    The message is a simple string, that may include newlines.
    String  message = NULL

XtNbuttons
    The buttons are created with labels which will be taken from the buttons resource. buttons is a string with the labels separated by vertiacl bars. If the string is empty, a single button with label ``Ok'' will be created.
    String  buttons = NULL

XtNlastChoice
    The last button that was selected is also the default for the next time (as soon as keyboard traversal has been implementedots) Buttons are numbered starting with 0. Set this resource to -1 if you don't want a default button.
    int  lastChoice = 0

XtNcallback
    When a button is clicked, the number of the button is stored in lastChoice, before the callback functions are called. The callbacks is passed the number in the call_data argument. The buttons are numbered starting at 0.
    <Callback> XtCallbackList  callback = NULL
    TransientShell
    Name | Class | Type | Default
    transientFor | XtCTransientFor | Widget | NULL
    WMShell
    Name | Class | Type | Default
    baseHeight | XtCBaseHeight | Int | XtUnspecifiedShellInt
    baseWidth | XtCBaseWidth | Int | XtUnspecifiedShellInt
    XtNtitle | XtCTitle | String | NULL
    titleEncoding | XtCTitleEncoding | Atom | XA_STRING
    XtNtransient | XtCTransient | Boolean | False
    waitForWm | XtCWaitForWm | Boolean | True
    winGravity | XtCWinGravity | Int | NULL
    wmTimeout | XtCWmTimeout | Int | 5000
    Shell
    Name | Class | Type | Default
    allowShellResize | XtCAllowShellResize | Boolean | False
    createPopupChildProc | XtCCreatePopupChildProc | XTCreatePopupChildProc | NULL
    XtNgeometry | XtCGeometry | String | NULL
    overrideRedirect | XtCOverrideRedirect | Boolean | False
    popdownCallback | XtCPopdownCallback | Callback | NULL
    popupCallback | XtCPopupCallback | Callback | NULL
    saveUnder | XtCSaveUnder | Boolean | False
    XtNvisual | XtCVisual | Visual * | CopyFromParent
    Composite
    Name | Class | Type | Default
    XtNchildren | XtCChildren | WidgetList | NULL
    insertPosition | XtCInsertPosition | XTOrderProc | NULL
    numChildren | XtCNumChildren | Cardinal | 0
    Core
    Name | Class | Type | Default
    XtNx | XtCX | Position | 0
    XtNy | XtCY | Position | 0
    XtNwidth | XtCWidth | Dimension | 0
    XtNheight | XtCHeight | Dimension | 0
    borderWidth | XtCBorderWidth | Dimension | 0
    XtNcolormap | XtCColormap | Colormap | NULL
    XtNdepth | XtCDepth | Int | 0
    destroyCallback | XtCDestroyCallback | XTCallbackList | NULL
    XtNsensitive | XtCSensitive | Boolean | True
    XtNtranslations | XtCTranslations | XTTranslations | NULL
    ancestorSensitive | XtCAncestorSensitive | Boolean | False
    accelerators | XtCAccelerators | XTTranslations | NULL
    borderColor | XtCBorderColor | Pixel | 0
    borderPixmap | XtCBorderPixmap | Pixmap | NULL
    background | XtCBackground | Pixel | 0
    backgroundPixmap | XtCBackgroundPixmap | Pixmap | NULL
    mappedWhenManaged | XtCMappedWhenManaged | Boolean | True
    XtNscreen | XtCScreen | Screen * | NULL

  Exports
As stated above, the alert widget can be created in the normal way as a Shell widget with a particular set of resources, but a more convenient way in many cases will be the XfwfDialog function. The function creates an alert box with an icon, message and buttons, pops it up, and returns only when the user has clicked one of the buttons. The function's result will be the number of the button that was clicked. The first argument, toplevel, will be the widget that is used as the alert's parent. Usually that will be the top level window of the application, but it need not be. The alert box will appear approximately in the middle of the toplevel widget (if the window manager allows it). The second argument is the name of the icon that will be shown in the upper left corner of the alert. It can be one of the built-in names "FATAL", "ERROR", "WARNING", "QUESTION", "INFO" and "NONE"; or it can be the name of a file that contains an icon in XPM format. The icon widget is of class XfwfIcon(3X11). It is named "_icon". The third argument is the message to display in the center of the alert. It may contain newlines. The message will be put into an XfwfLabel(3X11) widget, named, appropriately, "_message". The last argument, buttons, is a single string containing the labels for all buttons, separated with a vertical bar. If this argument is NULL, that doesn't mean that there will be no buttons. Instead, a single button with the label "OK" will be created. After all, if there are no buttons, how will the alert box ever disappear? The buttons are of type XfwfButton(3X11) and are named "1", "2", etc. The alert itself will simply be called "alert" and its child, an XfwfBoard(3X11) widget, will be called "_board". The implementation is as follows: After the alert has been created, XfwfDialog adds a callback to the alert widget, which will set the choice variable when a button is pressed. The function then enters a special purpose event loop, which dispatches events normally, but only until the choice variable is changed. The function returns with the value of choice def max(a, b) = ((a )>(b )?(a ):(b )) def min(a, b) = ((a )<(b )?(a ):(b ))
int  XfwfDialog(Widget  toplevel, String  icon, String  message, String  buttons)
{
    Widget alert;
    int choice = -1;
    XEvent event;
    Position x, y;
    Dimension wd, ht;
    XtVaGetValues
    (toplevel, XtNx, x, XtNy, y, XtNwidth, wd, XtNheight, ht, NULL);
    x = max(0, x + wd/2 - 120); y = max(0, y + ht/2 - 120);
    alert = XtVaCreatePopupShell
    ("alert", xfwfAlertWidgetClass, toplevel, XtVaTypedArg,
     XtNicon, XtRString, icon, strlen(icon) + 1, XtNmessage,
     message, XtNbuttons, buttons, XtNx, x, XtNy, y, NULL);
    XtAddCallback(alert, XtNcallback, button_pressed, choice);
    XtPopup(alert, XtGrabExclusive);
    while (choice == -1) {
    XtAppNextEvent(XtWidgetToApplicationContext(toplevel), event);
    XtDispatchEvent(event);
    }
    XtDestroyWidget(alert);
    return choice; }

Importss
incl
 <stdlib.h>
incl
 <Xfwf/Icon.h>
incl
 <Xfwf/Label.h>
incl
 <Xfwf/Board.h>
incl
 <Xfwf/Button.h>

  Private variables
The various widgets that make up the alert box are stored in private variables. button is an array of widgets, num_buttons is the length of the array.
Widget  iconw
Widget  labelw
Widget  boardw
Widget * buttonw
int  num_buttons

  Methods
The type converter is installed by the class_initialize method. It is the converter that is defined in the XfwfIcon class, but it needs to be installed here also, because XfwfAlert is not a subclass of XfwfIcon.
class_initialize()
{
    XtSetTypeConverter(XtRString, "Icon", cvtStringToIcon,
		       NULL, 0, XtCacheNone, NULL);
}
The initialize methods sets the local variables to NULL and then calls a utility function to create the children. The same function is used by the set_values method.
initialize(Widget  request, $, ArgList  args, Cardinal * num_args)
{
    $iconw = NULL;
    $labelw = NULL;
    $buttonw = NULL;
    $num_buttons = NULL;
    $boardw = XtVaCreateManagedWidget("board", xfwfBoardWidgetClass, $, NULL);
    create_children($);
}
set_values checks to see if any of the resources changed. If so, the old children are destroyed and new ones are made.
Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args)
{
    if ($old$icon != $icon || $old$message != $message
	|| $old$buttons != $buttons)
	create_children($);
    return False;
}

Utilities
def ALLOC = 1024 def myrealloc(p, size) = (void *)XtRealloc ((void *)p ,(size +ALLOC -1 )/ALLOC *ALLOC ) def mymalloc(size) = (void *)XtMalloc (size ) def myfree(p) = XtFree ((void *)p ) The button_pressed callback is used by the XfwfDialog function. It receives the number of the button that was pressed in the alert box as call_data and it has a reference to a variable as client_data. It simply copies the number to the variable and pops down the alert.
button_pressed(Widget  w, XtPointer  client_data, XtPointer  call_data)
{
    XtPopdown(w);
    *((int*) client_data) = (int) call_data;
}
The click callback is attached to each of the buttons. It sets the lastChoice resource and calls the callback routines of the alert widget.
click(Widget  w, XtPointer  client_data, XtPointer  call_data)
{
    Widget $ = XtParent(XtParent(w));
    $lastChoice = (int) client_data;
    XtCallCallbackList($, $callback, (XtPointer) $lastChoice);
}
The create_children function is called by initialize and set_values. It destroys the old children, except for the board, and creates new ones. The board is only resized, to fit the new children.
create_children($)
{
    int i;
    Dimension iconwd, iconht, labelwd, labelht, sumwd, wd, h, buttonht, ht;
    Dimension bframe, boffset, bw, bh;
    Position bx, by;
    String p;
    Widget board;
    char name[20];
    if ($iconw) XtDestroyWidget($iconw);
    if ($labelw) XtDestroyWidget($labelw);
    for (i = 0; i < $num_buttons; i++) XtDestroyWidget($buttonw[i]);
    $iconw = XtVaCreateManagedWidget
	("_icon", xfwfIconWidgetClass, $boardw, XtNx, 0, XtNy, 0,
	 XtNimage, $icon, XtNtraversalOn, False, NULL);
    XtVaGetValues($iconw, XtNwidth, iconwd, XtNheight, iconht, NULL);
    $labelw = XtVaCreateManagedWidget
	("_message", xfwfLabelWidgetClass, $boardw, XtNx, iconwd,
	 XtNy, 0, XtNshrinkToFit, True, XtNlabel, $message, NULL);
    XtVaGetValues($labelw, XtNwidth, labelwd, XtNheight, labelht, NULL);
    h = max(iconht, labelht);
    sumwd = iconwd;
    if ($buttons) {
	i = 0;
	buttonht = 0;
	p = strtok($buttons, "|");
	while (p) {
	    $buttonw = myrealloc($buttonw, (i+1)*sizeof(*$buttonw));
	    sprintf(name, "%d", i);
	    $buttonw[i] = XtVaCreateManagedWidget
		(name, xfwfButtonWidgetClass,
		 $boardw, XtNx, sumwd, XtNy, h, XtNshrinkToFit,
		 True, XtNlabel, p, NULL);
	    XtVaGetValues($buttonw[i], XtNwidth, wd, XtNheight, ht, NULL);
	    XtAddCallback
		($buttonw[i], XtNactivate, click, (XtPointer) i);
	    sumwd += wd;
	    buttonht = max(buttonht, ht);
	    i++;
	    p = strtok(NULL, "|");
	}
	$num_buttons = i;
    } else {
	$buttonw = mymalloc(2*sizeof(*$buttonw));
	$num_buttons = 1;
	$buttonw[0] = XtVaCreateManagedWidget
	    ("0", xfwfButtonWidgetClass, $boardw, XtNx, sumwd, XtNy, h,
	     XtNshrinkToFit, True, XtNlabel, " OK ", NULL);
	XtAddCallback($buttonw[0], XtNactivate, click, 0);
	XtVaGetValues
	    ($buttonw[0], XtNwidth, sumwd, XtNheight, buttonht, NULL);
    }
    board = $boardw;
    XfwfCallComputeInside(board, bx, by, bw, bh);
    wd = max(sumwd, iconwd + labelwd) + $board$width - bw;
    ht = h + buttonht + $board$height - bh;
    XtVaSetValues(board, XtNwidth, wd,  XtNheight, ht, NULL);
}