Subsections

Dialog Widgets

   

Any application needs to interact with the user. At the simplest level an application may need to inform, alert or warn the user about its current state. More advanced interaction may require the user to select or input data. Selecting files from a directory/file selection window is typical of an advanced example. Clearly, the provision of such interaction is the concern of the GUI. Motif provides a variety of Dialog widgets or Dialogs that facilitate most common user interaction requirements.

What are Dialogs?

Motif Dialog widgets usually comprise of the following components:

More advanced Dialogs (e.g. selection dialogs) may significantly enhance this model.

Dialogs have many distinct uses, indeed the Motif Style Guide  (Chapter 18) is specific in the use of each Dialog . The following Dialogs are provided by Motif:

WarningDialog
   -- Warns User about a program mishap.
ErrorDialog
   -- Alerts User to errors in the program.
InformationDialog
   -- Program Information supplied.
PromptDialog
   -- Allows user to supply data to program.
QuestionDialog
   -- Yes/No type queries.
WorkingDialog
   -- Notifies user if program is busy.
SelectionDialog
   -- Selection from a list of options.
FileSelectionDialog
   -- Specialised Selection Dialog to select directories and files.
BulletinBoardDialog
   -- Allows customised Dialogs to be created.

Basic Dialog Management

To create a Dialog use one of the XmCreate.....Dialog() functions.

Dialogs do not usually appear immediately on screen after creation or when the the initial application GUI is realized. Indeed, if an application runs successfully certain Dialog widgets (Error or Warning Dialogs, in particular) may never be required. However, prudent applications should consider all practical avenues that an application would be expected to take and provide suitable information (via Dialogs) to the user.

It is advisable to create all Dialogs when the application is initialised and the overall GUI is setup. However, Dialogs will not be managed initially. Recall Section 4.7) when a widget is unmanaged by its parent it will always be invisible.

Therefore, Dialogs are usually created unmanaged and displayed when required in the program as described below:

This method has the advantage that we only need to create a Dialog once and can then manage or unmanage it when necessary.

Most Motif Dialogs have default callback resources attached to the common Ok and Cancel. One consequence of these default callbacks is that they will unmanage the widgets from which they were called. However, if the application provides alternative callback (or other) functions then responsibility for correctly managing and unmanaging them is given over to the programmer.

The use of many dialogs is very similar. We will study a few specific Dialogs in detail.

The WarningDialog

  

This dialog is used to inform the user of a possible mistake in the program or in interaction with the program.

A typical example might be when you select the quit button (or menu item) to terminate the program -- if this was selected mistakenly, and there is no warning prompt, you have problems.

The dialog1.c  (Section 9.5) program attaches a pop-up WarningDialog when the quit menu option is selected (Fig 9.1). If you now select OK the program terminates, Cancel returns back to the program.

 

Fig. 9.1 WarningDialog and InformationDialog Widgets

To Create a WarningDialog:    



The function create_dialogs() in dialog1.c creates the WarningDialog in the following typical manner:

The InformationDialog Widget

  

The InformationDialog Widget is essentially the same as the WarningDialog, except that InformationDialogs are intended to supply program information or help. In terms of Motif creation and management the widgets are identical except that the XmCreateInformationDialog()   is used to create this class of Dialog. The main difference between the widgets to the user is visual. Motif employs different icons to distinguish between the two (Fig 9.1).

The program dialog1.c illustrates the creation and use of an InformationDialog Widget.

The dialog1.c program

   This program uses Warning and Information Dialogs. These Dialogs are based on the MessageBox widget and so we must include <Xm/MessageB.h> header file.

 
#include <Xm/Xm.h>
#include <Xm/MainW.h>
#include <Xm/CascadeB.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>

/* Prototype functions */

void create_dialogs(void);

/* callback for the pushbuttons.  pops up dialog */

void info_pop_up(Widget , char *, XmPushButtonCallbackStruct *),     
       quit_pop_up(Widget , char *, XmPushButtonCallbackStruct *);

void info_activate(Widget ), 
       quit_activate(Widget );

/* Global reference for dialog widgets */
Widget info, quit;
Widget info_dialog, quit_dialog;


main(int argc, char *argv[])
{
    XtAppContext app;
    Widget top_wid, main_w, menu_bar;
    
    top_wid = XtVaAppInitialize(&app, "Demos", NULL, 0,
        &argc, argv, NULL, NULL);

    main_w = XtVaCreateManagedWidget("main_window",
        xmMainWindowWidgetClass,   top_wid, 
        XmNheight, 300,
        XmNwidth,300,
        NULL);
        
        
    menu_bar = (Widget) XmCreateMenuBar(main_w, "main_list", NULL, 0);        
    XtManageChild(menu_bar);

        
    /* create quit widget + callback */
        
    quit = XtVaCreateManagedWidget( "Quit",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'Q',
        NULL);
        
    /* Callback has data passed to */
    
    XtAddCallback(quit, XmNactivateCallback, quit_pop_up, NULL); 

    
    /* create help widget + callback */
        
    info = XtVaCreateManagedWidget( "Info",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'I',
        NULL);    

    XtAddCallback(info, XmNactivateCallback, info_pop_up, NULL); 


    /* Create but do not show (manage) dialogs */

    create_dialogs();
    

    XtRealizeWidget(top_wid);
    XtAppMainLoop(app);
}

void create_dialogs()

 {  /* Create but do not manage dialog widgets */

    XmString xm_string;
    Arg args[1];


    /* Create InformationDialog */

    /* Label the dialog */

    xm_string = XmStringCreateLocalized("Dialog widgets added to \
                give info and check quit choice");
    XtSetArg(args[0], XmNmessageString, xm_string);

    /* Create the InformationDialog */

    info_dialog = XmCreateInformationDialog(info, "info", args, 1);

    XmStringFree(xm_string);

    XtAddCallback(info_dialog, XmNokCallback, info_activate, NULL);

    /* Create Warning DIalog */

    /* label the dialog */

    xm_string = 
      XmStringCreateLocalized("Are you sure you want to quit?");
    XtSetArg(args[0], XmNmessageString, xm_string);

    /* Create the WarningDialog */
    quit_dialog = XmCreateWarningDialog(quit, "quit", args, 1);

    XmStringFree(xm_string);

    XtAddCallback(quit_dialog, XmNokCallback, quit_activate, NULL);

}


void info_pop_up(Widget cascade_button, char *text, 
                 XmPushButtonCallbackStruct *cbs)

{
    XtManageChild(info_dialog);
}

void quit_pop_up(Widget cascade_button, char *text, 
                 XmPushButtonCallbackStruct *cbs)

{
    XtManageChild(quit_dialog);
}

/* callback routines for dialogs */

void info_activate(Widget dialog)
{
    printf("Info Ok was pressed.\n");
}

void quit_activate(Widget dialog)
{
    printf("Quit Ok was pressed.\n");
    exit(0);
}

Error, Working and Question Dialogs

        

These 3 Dialogs are similar to both the Information and Warning Dialogs. They are created and used in similar fashions. The main difference again being the icon used to depict the Dialog class as illustrated in Figs. 9.2 -- 9.4.

 

Fig. [*] ErrorDialog Widget  

Fig. [*] WorkingDialog Widget  

Fig. [*] QuestionDialog Widget

Unwanted Dialog Buttons

  

When you create a Dialog, Motif will create 3 buttons by default -- Ok, Cancel and Help. There are many occasions when it is not natural to require the use of three buttons within an application. For instance in dialog1.c we only really need the user to acknowledge the InformationDialog and no user should need any help to choose whether to quit our program.

Motif provides a mechanism to disable unwanted buttons in a Dialog.



To remove a button:



An example where we disable the Cancel and Help buttons on the InformationDialog and the Help button on the WarningDialog from the Dialogs created in program dialog1.c is shown in Fig. 9.5. The code that performs the task of deleting the Help from a widget, dialog is as follows:

   Widget remove; 

   remove = XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON);
   
   XtUnmanageChild(remove);

 

Fig. 9.5 Removed Dialog Button

The PromptDialog Widget

  

The PromptDialog widget is slightly more advanced than the classes of Dialog widgets encountered so far. This widget allows the user to enter text (Fig. 9.6).

The function XmCreatePromptDialog()   instantiates the Dialog. Typically two resources  of a PromptDialog widget are required to be set. These resources are

XmNselectionLabelString
 -- the prompt message, an XmString data type.
XmNtextString
  -- the default response XmString which may be empty.

Note: A Prompt Dialog is based on the SelectionBox widget and so we must include <Xm/SelectioB.h> header file.

The prompt.c program

This program, an extension of dialog1.c, creates a PromptDialog into which the user can enter text. The PromptDialog first displayed by this program is shown in Fig. 9.6. The text is echoed in an InformationDialog which is created in a Prompt callback function, prompt_activate().

 

Fig. 9.6 PromptDialog Widget

A PromptDialog Callback  has the following structure

 void prompt_callback(Widget widget, XtPointer client_data,
XmSelectionBoxCallbackStruct *selection)

Normally, we will only be interested in obtaining the string entered to the PromptDialog. An element of the XmSelectionBoxCallbackStruct, value holds the (XmString data type) value.

In prompt.c, the callback for the prompt dialog (activated with Ok button) -- prompt_activate().

This function uses the selection->value XmString to set up the InformationDialog message String.

Note, that since a PromptDialog is a SelectionBox widget type we must use XmSelectionBoxGetChild() to find any buttons we may wish to remove from the PromptDialog. In prompt.c we remove the Help button in this way.

 
#include <Xm/Xm.h> 
#include <Xm/MainW.h> 
#include <Xm/CascadeB.h> 
#include <Xm/MessageB.h> 
#include <Xm/PushB.h> 
#include <Xm/SelectioB.h>

/* Callback and other function prototypes */

void ScrubDial(Widget, int);
void info_pop_up(Widget  , char *, XmPushButtonCallbackStruct *), 
     quit_pop_up(Widget  , char *, XmPushButtonCallbackStruct *), 
     prompt_pop_up(Widget  , char *, XmPushButtonCallbackStruct *); 
void prompt_activate(Widget , caddr_t, 
                   XmSelectionBoxCallbackStruct *);
void quit_activate(Widget);

Widget top_wid;

main(int argc, char *argv[]) 

{
    XtAppContext app;
    Widget main_w, menu_bar, info, prompt, quit;

    
    top_wid = XtVaAppInitialize(&app, "Demos", NULL, 0,
        &argc, argv, NULL, NULL);

    main_w = XtVaCreateManagedWidget("main_window",
        xmMainWindowWidgetClass,   top_wid, 
        XmNheight, 300,
        XmNwidth,300,
        NULL);

        
    menu_bar = XmCreateMenuBar(main_w, "main_list", 
        NULL, 0);        
    XtManageChild(menu_bar);
       
    /* create prompt widget + callback */       
    prompt = XtVaCreateManagedWidget( "Prompt",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'P',
        NULL);
                
    /* Callback has data passed to */   
    XtAddCallback(prompt, XmNactivateCallback, 
                  prompt_pop_up, NULL);

    
    
    /* create quit widget + callback */
        
    quit = XtVaCreateManagedWidget( "Quit",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'Q',
        NULL);
        
        
    /* Callback has data passed to */
    
    XtAddCallback(quit, XmNactivateCallback, quit_pop_up, 
                  "Are you sure you want to quit?");

    
    /* create help widget + callback */
        
    info = XtVaCreateManagedWidget( "Info",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'I',
        NULL);    

    XtAddCallback(info, XmNactivateCallback, info_pop_up, 
            "Select Prompt Option To Get Program Going."); 
    
    XtRealizeWidget(top_wid);
    XtAppMainLoop(app); }

 void prompt_pop_up(Widget cascade_button, char *text, 
XmPushButtonCallbackStruct *cbs)

{   Widget dialog, remove;
    XmString xm_string1, xm_string2;
    Arg args[3];

    /* label the dialog */
    xm_string1 = XmStringCreateLocalized("Enter Text Here:");
    XtSetArg(args[0], XmNselectionLabelString, xm_string1);
    /* default text string  */
    xm_string2 = XmStringCreateLocalized("Default String");

   
    XtSetArg(args[1], XmNtextString, xm_string2);
   /* set up default button for cancel callback */
    XtSetArg(args[2], XmNdefaultButtonType, 
                    XmDIALOG_CANCEL_BUTTON);

    /* Create the WarningDialog */
    dialog = XmCreatePromptDialog(cascade_button, "prompt", 
                                  args, 3);
    
    XmStringFree(xm_string1);
    XmStringFree(xm_string2);

   
    XtAddCallback(dialog, XmNokCallback, prompt_activate, 
                  NULL);
   /* Scrub Prompt Help Button */
    remove = XmSelectionBoxGetChild(dialog, 
                      XmDIALOG_HELP_BUTTON);
   
    XtUnmanageChild(remove);  /* scrub HELP button */ 
    
    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); }

 void info_pop_up(Widget cascade_button, char *text, 
XmPushButtonCallbackStruct *cbs)

{   Widget dialog;
    XmString xm_string;
    extern void info_activate();
    Arg args[2];

    /* label the dialog */
    xm_string = XmStringCreateLocalized(text);
    XtSetArg(args[0], XmNmessageString, xm_string);
    /* set up default button for OK callback */
    XtSetArg(args[1], XmNdefaultButtonType, 
             XmDIALOG_OK_BUTTON);

   
    /* Create the InformationDialog as child of 
       cascade_button passed in */
    dialog = XmCreateInformationDialog(cascade_button, 
                                       "info", args, 2);
    
    ScrubDial(dialog, XmDIALOG_CANCEL_BUTTON);
    ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

    XmStringFree(xm_string);

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); 
}

 void quit_pop_up(Widget cascade_button, char *text, 
XmPushButtonCallbackStruct *cbs) 

{   Widget dialog;
    XmString xm_string;
    Arg args[1];

    /* label the dialog */
    xm_string = XmStringCreateLocalized(text);
    XtSetArg(args[0], XmNmessageString, xm_string);
    /* set up default button for cancel callback */
    XtSetArg(args[1], XmNdefaultButtonType, 
                   XmDIALOG_CANCEL_BUTTON);

    /* Create the WarningDialog */
    dialog = XmCreateWarningDialog(cascade_button, "quit", 
                                   args, 1);
    
    ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

    XmStringFree(xm_string);

    XtAddCallback(dialog, XmNokCallback, quit_activate, 
                  NULL);

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); 
}

 /* routine to remove a DialButton from a Dialog */

void ScrubDial(Widget wid, int dial)

{  Widget remove;

   remove = XmMessageBoxGetChild(wid, dial);
   
   XtUnmanageChild(remove); 
}

 /* callback function for Prompt activate */

void prompt_activate(Widget widget, XtPointer client_data,
XmSelectionBoxCallbackStruct *selection)

{   Widget dialog;
    Arg args[2];
    XmString xm_string;
    
    /* compose InformationDialog output string */
    /* selection->value holds XmString entered to prompt */
    
    xm_string = XmStringCreateLocalized("You typed: ");
    xm_string = XmStringConcat(xm_string,selection->value);

 
    XtSetArg(args[0], XmNmessageString, xm_string);
    /* set up default button for OK callback */
    XtSetArg(args[1], XmNdefaultButtonType, 
             XmDIALOG_OK_BUTTON);
  
    /* Create the InformationDialog to echo 
       string grabbed from prompt */
    dialog = XmCreateInformationDialog(top_wid, 
           "prompt_message", args, 2);
    
    ScrubDial(dialog, XmDIALOG_CANCEL_BUTTON);
    ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); 
}

/* callback routines for quit ok dialog */


void quit_activate(Widget dialog) {
    printf("Quit Ok was pressed.\n");
    exit(0); 
}

Selection and FileSelection Dialogs

     

The purpose of both these widgets is to allow the user to select from a list (or in set of lists) displayed within the Dialog. The creation and use of Selection and FileSelection Dialogs is similar. The FileSelectionDialog (Fig. 9.7) allows the selection of files from a directory which has use in many applications (text editors, graphics programs etc.) The FileSelection Dialog provides a means for merely browsing directories and selecting file names. It is up to the application to read/write the file, or to use the file name appropriately. The SelectionDialog allows for more general selection. We will study the FileSelectionDialog as it is more complex and it is also more commonly used.

 

Fig. 9.7 The FileSelectionDialog Widget

To create a FileSelectionDialog , the XmCreateFileSelectionDialog()  function is commonly used. You must include the <Xm/FileSB.h> header file.

A FileSelectionDialog has many resources  you can set to control the search of files: (All resources are XmString data types except where indicated.)

XmNdirectory
  -- The directory from where files are (initially) listed. The default directory is the current working directory.
XmNdirListLabelString
  -- The label displayed above the directory listing in Dialog.
XmNdirMask
  -- The mask used to filter out certain files. E.g. in file_select.c  this mask is set to *.c so as only to list C source files in the dialog.
XmNdirSpec
  -- the name of the file (to be) chosen.
XmNfileListLabelString
  -- The label displayed above the file list.
XmNfileTypeMask
  -- The type of file to be listed (char type). XmFILE_REGULAR, XmFILE_DIRECTORY, XmFILE_TYPE_ANY are conveniently predefined macros in <Xm/FileSB.h>.
XmNfilterLabelString
  -- The label displayed above the filter list.

The search directory, directory mask and others can be altered from within the Dialog window.

The FileSelectionDialog has many child widgets under its control. It is sometimes useful to take control of these child widget  in order to have greater control of their resources or callback  or even to remove (XtUnmanageChild()) one. The function XmFileSelectionBoxGetChild()  is used to return the ID of a specified child widget. The function takes two arguments:

Widget
-- the parent widget.
Child
-- an unsigned char. Possible values for this argument are defined in <Xm/FileSB.h> and include:

XmDIALOG_APPLY_BUTTON, 		 XmDIALOG_LIST, 
XmDIALOG_CANCEL_BUTTON, 		 XmDIALOG_LIST_LABEL,
XmDIALOG_DEFAULT_BUTTON, TXmDIALOG_OK_BUTTON, 
XmDIALOG_DIR_LIST, 		 XmDIALOG_SELECTION_LABEL, 
XmDIALOG_DIR_LIST_LABEL, 		 XmDIALOG_SEPARATOR, 
XmDIALOG_FILTER_LABEL, 		 XmDIALOG_TEXT, 
XmDIALOG_FILTER_TEXT, 		 XmDIALOG_WORK_AREA, 
XmDIALOG_HELP_BUTTON. 		  

The file_select.c program

The program file_select.c  simply looks for C source files in a directory -- the XmNdirMask resource is set to filter out only *.c files. If a file is selected it's listing is printed to standard output.

 
#include <stdio.h>

#include <Xm/Xm.h> 
#include <Xm/MainW.h> 
#include <Xm/CascadeB.h> 
#include <Xm/MessageB.h> 
#include <Xm/PushB.h> 
#include <Xm/FileSB.h>


/* prototype callbacks and other functions */
void  quit_pop_up(Widget , char *, 
                  XmPushButtonCallbackStruct *), 
void  select_pop_up(Widget , char *, 
                   XmPushButtonCallbackStruct *); 
void ScrubDial(Widget, int);
void select_activate(Widget , XtPointer , 
                     XmFileSelectionBoxCallbackStruct *)
void quit_activate(Widget)
void cancel(Widget , XtPointer , 
            XmFileSelectionBoxCallbackStruct *);
void error(char *, char *);

File *fopen();

Widget top_wid;
 

main(int argc, char *argv[]) 

{
    XtAppContext app;
    Widget main_w, menu_bar, file_select, quit;
    
    
    top_wid = XtVaAppInitialize(&app, "Demos", NULL, 0,
        &argc, argv, NULL, NULL);

    main_w = XtVaCreateManagedWidget("main_window",
        xmMainWindowWidgetClass,   top_wid, 
        XmNheight, 300,
        XmNwidth,300,
        NULL);

    menu_bar = XmCreateMenuBar(main_w, "main_list", 
        NULL, 0);        
    XtManageChild(menu_bar);

        
    /* create prompt widget + callback */
        
    file_select = XtVaCreateManagedWidget( "Select",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'S',
        NULL);

               
    /* Callback has data passed to */
    XtAddCallback(file_select, XmNactivateCallback, 
                  select_pop_up, NULL);
        
    /* create quit widget + callback */    
    quit = XtVaCreateManagedWidget( "Quit",
        xmCascadeButtonWidgetClass, menu_bar,
        XmNmnemonic, 'Q',
        NULL);

                
    /* Callback has data passed to */
    XtAddCallback(quit, XmNactivateCallback, quit_pop_up, 
                  "Are you sure you want to quit?");  

    XtRealizeWidget(top_wid);
    XtAppMainLoop(app); 
}

 
void select_pop_up(Widget cascade_button, char *text, 
                   XmPushButtonCallbackStruct *cbs)

{   Widget dialog, remove;
    XmString mask;
    Arg args[1];
       
    /* Create the FileSelectionDialog */     
    mask  = XmStringCreateLocalized("*.c");
    XtSetArg(args[0], XmNdirMask, mask);

 
    dialog = XmCreateFileSelectionDialog(cascade_button, 
           "select", args, 1);        
    XtAddCallback(dialog, XmNokCallback, select_activate, 
                  NULL);
    XtAddCallback(dialog, XmNcancelCallback, cancel, NULL);

    remove = XmSelectionBoxGetChild(dialog, 
           XmDIALOG_HELP_BUTTON);
   
    XtUnmanageChild(remove); /* delete HELP BUTTON */
    

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); 
}

 
void quit_pop_up(Widget cascade_button, char *text, 
                 XmPushButtonCallbackStruct *cbs)

{   Widget dialog;
    XmString xm_string;
    Arg args[2];

    /* label the dialog */
    xm_string = XmStringCreateLocalized(text);
    XtSetArg(args[0], XmNmessageString, xm_string);
    /* set up default button for cancel callback */
    XtSetArg(args[1], XmNdefaultButtonType, 
             XmDIALOG_CANCEL_BUTTON);

    /* Create the WarningDialog */
    dialog = XmCreateWarningDialog(cascade_button, "quit", 
           args, 2);
    
    ScrubDial(dialog, XmDIALOG_HELP_BUTTON);

    XmStringFree(xm_string);

    XtAddCallback(dialog, XmNokCallback, quit_activate, 
                  NULL);

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone); 
}

 /* routine to remove a DialButton from a Dialog */

void ScrubDial(Widget wid, int dial)

{  Widget remove;

   remove = XmMessageBoxGetChild(wid, dial);  
   XtUnmanageChild(remove);    
}

 
/* callback function for Prompt activate */

void select_activate(Widget widget, XtPointer client_data, 
                     XmFileSelectionBoxCallbackStruct *selection)

{   /* function opens file (text) and prints to stdout */

    FILE *fp;
    char *filename, line[200];
    
    
    XmStringGetLtoR(selection->value, 
 XmSTRING_DEFAULT_CHARSET, &filename);

   
    if ( (fp = fopen(filename,"r")) == NULL) 
      error("CANNOT OPEN FILE", filename);
  else
    {  while ( !feof(fp) )
          { fgets(line,200,fp);
            printf("%s\n",line);
          }           
       fclose(fp);         
    }           
}

 
void cancel(Widget widget, XtPointer client_data, 
            XmFileSelectionBoxCallbackStruct *selection)

{ XtUnmanageChild(widget);  /* undisplay widget */    
}

void error(char *s1, char *s2)

{  /* prints error to stdout */ 
  
   
   printf("%s: %s\n", s1, s2);
   exit(-1);
   
}

 /* callback routines for quit ok dialog */


void quit_activate(Widget dialog) 

{
    printf("Quit Ok was pressed.\n");
    exit(0); 

}

User Defined Dialogs

Motif allows the programmer to create new customised Dialogs. BulletinBoardDialogs   and FormDialogs   let you place widgets within them in a similar fashion to their corresponding BulletinBoard and Form widgets. We will, therefore, not deal with these further in this text.

Exercises

Exercise 6981

Rewrite the error() function of the file_select.c program so that errors trapped by this program are displayed in an ErrorDialog widget and not simply printed to standard output.



Dave Marshall
1/5/1999