home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / master12.zip / mastering / diskuse.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  21KB  |  713 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <Xm/MainW.h>
  6. #include <Xm/BulletinB.h>
  7. #include <Xm/CascadeB.h>
  8. #include <Xm/Form.h>
  9. #include <Xm/LabelG.h>
  10. #include <Xm/MessageB.h>
  11. #include <Xm/RowColumn.h>
  12. #include <Xm/Text.h>
  13. #include <Xm/TextF.h>
  14. #include <Xm/PushB.h>
  15. #include <Xm/Separator.h>
  16.  
  17. /* information for 'what' */
  18. char ident1[]="@(#)diskuse Version 1.2.0 July 29, 1992";
  19.  
  20. /*-------------------------------------------------------------
  21. ** Forward Declarations
  22. */
  23.  
  24. void main();
  25. void arm1CB ();
  26. void arm2CB ();
  27. void arm3CB ();
  28. void errorCB ();
  29. void execdu ();
  30. void inputCB ();
  31. void textf_activateCB();
  32. Widget create_dlog ();
  33. Widget CreateHelp ();
  34. Widget CreateVersion ();
  35. void HelpCB ();
  36. void VersionCB ();
  37. void QuitCB ();
  38.  
  39. /*-------------------------------------------------------------
  40. ** Global Variables
  41. */
  42.  
  43. #define MAX_ARGS 20
  44. #define BUFFERSZ 40000
  45.  
  46. XtAppContext app_context;
  47. static XmStringCharSet charset = (XmStringCharSet) XmFONTLIST_DEFAULT_TAG;
  48. String specified_dir;
  49. Widget scroll_text, errmsg_box, pbg;
  50.  
  51. /*-------------------------------------------------------------
  52. **  arm1CB      - callback for home directory usage button
  53. */
  54. void arm1CB (w, client_data, call_data) 
  55. Widget     w;            /*  widget ID              */
  56. XtPointer  client_data;  /*  data from application  */
  57. XtPointer  call_data;    /*  data from widget class */
  58. {
  59.   Widget   message_box;  /*  Message Dialog         */
  60.   int      flag;
  61.  
  62.   /*  Create dialog. */
  63.   flag = 1;
  64.   message_box = create_dlog (w, flag);
  65.   execdu (message_box, flag);
  66.  
  67. }
  68.  
  69. /*-------------------------------------------------------------
  70. **  execdu  - execute fork to get du information
  71. */
  72.  
  73. void execdu (messageBox, flag)
  74.     Widget        messageBox;
  75.   int     flag;
  76. {
  77.     int     pid;
  78.     int     to_parent_fds[2];
  79.     char   homedir[25];
  80.  
  81.     /*
  82.      *  Add the alternate input callback.
  83.      */
  84.  
  85.     XtAppAddInput (app_context, 0, XtInputReadMask, inputCB, messageBox); 
  86.  
  87.     /*
  88.      *  Fork and exec 'ps' to trigger creation of the selection box.
  89.      */
  90.  
  91.     pipe (to_parent_fds);
  92.     pid = fork ();
  93.     if (pid == 0)
  94.     {
  95.   /*
  96.    *  Child (application) process:
  97.    *    application --> to_parent_fds[1].
  98.    *    close other files and exec the application.
  99.    */
  100.  
  101.       close (1);
  102.     dup (to_parent_fds[1]);
  103.     close (to_parent_fds[0]);
  104.     close (to_parent_fds[1]);
  105.   
  106.     if (flag == 1) {
  107.     sprintf (homedir, "%s", getenv("HOME"));
  108.     execlp ("du", "du", homedir, 0);
  109.     }
  110.     if (flag == 2)
  111.     execlp ("du", "du", 0);
  112.     if (flag == 3)
  113.     execlp ("bdf", "bdf", 0);
  114.     if (flag == 4) {
  115.     execlp ("du", "du", specified_dir, 0);
  116.     }
  117.     }
  118.     else if (pid > 0)
  119.     {
  120.   /*
  121.    *  Parent (client) process:
  122.    *    to_parent_fds[0] --> client
  123.    *    close other files and turn off buffering.
  124.    */
  125.  
  126.         close (0);
  127.   dup (to_parent_fds[0]);
  128.   close (to_parent_fds[0]);
  129.   close (to_parent_fds[1]);
  130.   setbuf (stdout, NULL);
  131.     }
  132.     else
  133.     {
  134.   fprintf (stderr, "Unable to fork process\n");
  135.   exit (1);
  136.     }
  137. }
  138.  
  139. /************************************************************************
  140.  *  inputCB
  141.  ***********************************************************************/
  142.  
  143. void
  144. inputCB (messageBox, fd, id)
  145.     Widget        messageBox;
  146.     int          *fd;
  147.     XtInputId    *id;
  148. {
  149.     char      buf[BUFFERSZ];
  150.     int       n, nitems, nbytes;
  151.     XmString  message_string = NULL;
  152.     Arg       args[3];
  153.  
  154.     nbytes = read (*fd, buf, BUFFERSZ);
  155.     if (nbytes)
  156.     {
  157.   /*
  158.    *  Replace the tab character (\011) with a blank (\040) */
  159.  
  160.         for (n = 0; n < nbytes; n++)
  161.         {
  162.       if (buf[n] == '\011')
  163.           buf[n] = '\040';
  164.         }
  165.    
  166.         XtRemoveInput (*id);
  167.  
  168.         n = 0;
  169.         XtSetArg (args[n], XmNvalue, buf); n++;
  170.         XtSetValues (scroll_text, args, n);
  171.  
  172.         XtManageChild (messageBox); 
  173.  
  174.     /* Fill buf with NULL for the next read */
  175.         for (n = 0; n < nbytes; n++)
  176.         buf[n] = NULL;
  177.    
  178.       XmStringFree (message_string);
  179.     }
  180. }
  181.  
  182. /*-------------------------------------------------------------
  183. **  arm2CB      - callback for current directory usage button
  184. */
  185. void arm2CB (w, client_data, call_data) 
  186. Widget      w;               /*  widget ID               */
  187. XtPointer   client_data;     /*  data from application   */
  188. XtPointer   call_data;       /*  data from widget class  */
  189. {
  190.   Widget    message_box;     /*  message box             */
  191.   Arg       args[MAX_ARGS];  /*  arg list                */
  192.   register  int  n;          /*  arg count               */
  193.   int       flag;
  194.  
  195.   /*  Create message box dialog. */
  196.   flag = 2;
  197.   message_box = create_dlog (w, flag);
  198.   execdu (message_box, flag);
  199. }
  200.  
  201. /*-------------------------------------------------------------
  202. **  arm3CB      - callback for current directory usage button
  203. */
  204. void arm3CB (w, client_data, call_data) 
  205. Widget     w;            /*  widget ID              */
  206. XtPointer  client_data;  /*  data from application  */
  207. XtPointer  call_data;    /*  data from widget class */
  208. {
  209.   Widget   message_box;  /*  message box            */
  210.   int      flag;
  211.  
  212.   /*  Create message box dialog. */
  213.   flag = 3;
  214.   message_box = create_dlog (w, flag);
  215.   execdu (message_box, flag);
  216. }
  217.  
  218. /*-------------------------------------------------------------
  219. **  errorCB      - callback for continue button in message area
  220. */
  221. void errorCB (w, client_data, call_data) 
  222. Widget     w;            /*  widget ID               */
  223. XtPointer  client_data;  /*  data from application   */
  224. XtPointer  call_data;    /*  data from widget class  */
  225. {
  226.   int      n;
  227.   Arg      args[10];
  228.   XmString   label_text;
  229.  
  230.   /*  Blank error message in main window message area. */
  231.   label_text = XmStringCreateLtoR ("Error Message Window", charset);
  232.   n = 0;
  233.   XtSetArg(args[n], XmNlabelString, label_text); n++;
  234.   XtSetValues (errmsg_box, args, n);
  235.   XtUnmanageChild (pbg);
  236.   XmStringFree (label_text);
  237. }
  238.  
  239. /*-------------------------------------------------------------
  240. **  textf_activateCB  - callback for user specified directory 
  241. */
  242. void textf_activateCB (w, client_data, call_data) 
  243. Widget     w;                /*  widget ID    */
  244. XtPointer  client_data;      /*  data from application   */
  245. XtPointer  call_data;        /*  data from widget class  */
  246. {
  247.   Widget      message_box;     /*  message box    */
  248.   Widget      button;
  249.   Arg         args[MAX_ARGS];  /*  arg list    */
  250.   register    int  n;          /*  arg count    */
  251.   int         flag, stat_val;
  252.   struct stat bufr;
  253.   static char errmsg[BUFFERSZ];
  254.   XmString    errormsg;
  255.  
  256.     /* Get user specified directory from text field widget */
  257.   n = 0;
  258.   XtSetArg (args[n], XmNvalue, &specified_dir);  n++;
  259.   XtGetValues (w, args, n);
  260.  
  261.   /* Check for validity of directory path */
  262.   stat_val = stat (specified_dir, &bufr);
  263.  
  264.   if (stat_val == 0){
  265.  
  266.   /*  Create message box dialog. */
  267.   flag = 4;
  268.   message_box = create_dlog (w, flag);
  269.   execdu (message_box, flag);
  270.   }
  271.   else {
  272.     sprintf (errmsg, "Error!  The input directory is probably invalid.\0");
  273.     errormsg = XmStringCreateLtoR (errmsg, charset);
  274.     n = 0;
  275.     XtSetArg (args [n], XmNlabelString, errormsg); n++;
  276.     XtSetValues (errmsg_box, args, n);
  277.     XtManageChild (pbg);
  278.   }
  279. }
  280.  
  281. /*-------------------------------------------------------------
  282. **  HelpCB      - callback for help button
  283. */
  284. void HelpCB (w, client_data, call_data) 
  285. Widget     w;            /*  widget ID              */
  286. XtPointer  client_data;  /*  data from application  */
  287. XtPointer  call_data;    /*  data from widget class */
  288. {
  289.   Widget   message_box;  /*  message box            */
  290.  
  291.  
  292.   /*  Create help window. */
  293.   message_box = CreateHelp (w);
  294.  
  295.  
  296.   /*  Display help window. */
  297.   XtManageChild (message_box);
  298. }
  299.  
  300. /*-------------------------------------------------------------
  301. **  VersionCB      - callback for help button
  302. */
  303. void VersionCB (w, client_data, call_data) 
  304. Widget     w;            /*  widget ID               */
  305. XtPointer  client_data;  /*  data from application   */
  306. XtPointer  call_data;    /*  data from widget class  */
  307. {
  308.   Widget   message_box;  /*  message box             */
  309.  
  310.  
  311.   /*  Create message window. */
  312.   message_box = CreateVersion (w);
  313.  
  314.  
  315.   /*  Display version window. */
  316.   XtManageChild (message_box);
  317. }
  318.  
  319. /*-----------------------------------------------------------------
  320. **  create_dlog    - create a custom dialog with a scrolled window
  321. */
  322. Widget create_dlog (parent, flag) 
  323.   Widget   parent;            /*  parent widget */
  324.   int      flag;
  325. {
  326.   Widget   form, sep, button;
  327.   Arg      args[MAX_ARGS];    /*  arg list      */
  328.   register int  n;            /*  arg count     */
  329.   XmString button_string = NULL;
  330.   XmString title_string = NULL;
  331.  
  332.   static char *titles[5] =
  333.   { NULL,
  334.     "Home Directory Usage",
  335.     "Current Directory Usage",
  336.     "File Space Available",
  337.     "User Specified Directory",
  338.   };
  339.  
  340.  
  341. /* Create a form dialog (dialog shell and form widget) */
  342.   title_string = XmStringCreateLtoR(titles[flag],charset);
  343.   n =0;
  344.   XtSetArg (args[n], XmNdialogTitle, title_string);  n++;
  345.   form = XmCreateFormDialog (parent, "form", args, n);
  346.  
  347. /* Create a scrolled window widget as a child of the form */
  348.   n = 0;
  349.   XtSetArg (args[n], XmNbottomOffset, 10);  n++;
  350.   XtSetArg (args[n], XmNtopOffset, 10);  n++;
  351.   XtSetArg (args[n], XmNleftOffset, 10);  n++;
  352.   XtSetArg (args[n], XmNrightOffset, 10);  n++;
  353.   XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);  n++;
  354.   XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
  355.   XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);  n++;
  356.   XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT);  n++;
  357.   XtSetArg (args[n], XmNeditable, False);  n++;
  358.   scroll_text = XmCreateScrolledText (form, "scroll_text", args, n);
  359.   XtManageChild (scroll_text);
  360.  
  361. /* Create a pushbutton to close the dialog */
  362.   button_string = XmStringCreateLtoR ("Close", charset);
  363.   n = 0;
  364.   XtSetArg (args[n], XmNleftOffset, 335);  n++;
  365.   XtSetArg (args[n], XmNbottomOffset, 10);  n++;
  366.   XtSetArg (args[n], XmNtopOffset, 10);  n++;
  367.   XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);  n++;
  368.   XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
  369.   XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);  n++;
  370.   XtSetArg (args[n], XmNtopWidget, scroll_text);  n++;
  371.   XtSetArg (args[n], XmNlabelString, button_string);  n++;
  372.   XtSetArg (args[n], XmNshowAsDefault, True);  n++;
  373.   XtSetArg (args[n], XmNdefaultButtonShadowThickness, 2);  n++;
  374.   XtSetArg (args[n], XmNheight, 30);  n++;
  375.   XtSetArg (args[n], XmNwidth, 80);  n++;
  376.   button = XmCreatePushButton (form, "button", args, n);
  377.   XtManageChild (button);
  378.  
  379. /* Set the defaultButton resource so behavior complies with style guide */
  380.   n = 0;
  381.   XtSetArg (args[n], XmNdefaultButton, button);  n++;
  382.   XtSetValues (form, args, n);
  383.  
  384. /*  Free strings */
  385.   if (title_string) XmStringFree (title_string);
  386.   if (button_string) XmStringFree (button_string);
  387.  
  388.   return (form);
  389. }
  390.  
  391. /*-------------------------------------------------------------
  392. **  CreateHelp    - create help window
  393. */
  394. Widget CreateHelp (parent) 
  395.   Widget       parent;             /*  parent widget  */
  396. {
  397.   Widget       button;
  398.   Widget       message_box;        /*  Message Dialog */
  399.   Arg          args[MAX_ARGS];     /*  arg list       */
  400.   register int n;                  /*  arg count      */
  401.  
  402.   static char  message[BUFFERSZ];  /*  help text      */
  403.   XmString     title_string = NULL;
  404.   XmString     message_string = NULL;
  405.   XmString     button_string = NULL;
  406.  
  407.   /*  Generate message to display. */
  408.   sprintf (message, "\
  409. This program provides a quick means of finding the disk space used \n\
  410. by a particular directory.  You can enter a specific directory path \n\
  411. in the text field widget labeled 'Enter Directory Here' and press \n\
  412. Return or move the pointer to one of the buttons and click button 1.  \n\
  413. Another window will appear with a scrolled text containing the \n\
  414. information you want.  There may be a slight time delay before this \n\
  415. window appears.  To remove this window, move the pointer to the \n\
  416. Close button and click button 1.  To exit the \n\
  417. program, move the pointer to the File button and click button 1.  An Exit \n\
  418. button appears.  Move the pointer into the Exit button and click \n\
  419. button 1.  There is a time delay before the program is terminated.\0");
  420.  
  421.   /* Create the compound strings */
  422.   message_string = XmStringCreateLtoR (message, charset);
  423.   button_string = XmStringCreateLtoR ("Close", charset);
  424.   title_string = XmStringCreateLtoR ("diskuse help", charset);
  425.  
  426.   /*  Create message box dialog. */
  427.   n = 0;
  428.   XtSetArg (args[n], XmNdialogTitle, title_string);  n++;
  429.   XtSetArg (args[n], XmNokLabelString, button_string);  n++;
  430.   XtSetArg (args[n], XmNmessageString, message_string);  n++;
  431.   message_box = XmCreateMessageDialog (parent, "helpbox", args, n);
  432.  
  433.   button = XmMessageBoxGetChild (message_box, XmDIALOG_CANCEL_BUTTON);
  434.   XtUnmanageChild (button);
  435.   button = XmMessageBoxGetChild (message_box, XmDIALOG_HELP_BUTTON);
  436.   XtUnmanageChild (button);
  437.  
  438.  
  439.   /*  Free strings and return message box. */
  440.   if (title_string) XmStringFree (title_string);
  441.   if (message_string) XmStringFree (message_string);
  442.   if (button_string) XmStringFree (button_string);
  443.   return (message_box);
  444. }
  445.  
  446. /*-------------------------------------------------------------
  447. **  CreateVersion    - create version window
  448. */
  449. Widget CreateVersion (parent) 
  450.   Widget        parent;             /*  parent widget  */
  451. {
  452.   Widget        button;
  453.   Widget        message_box;        /*  Message Dialog */
  454.   Arg           args[MAX_ARGS];     /*  arg list       */
  455.   register int  n;                  /*  arg count      */
  456.  
  457.   static char   message[BUFFERSZ];  /*  help text      */
  458.   XmString      title_string = NULL;
  459.   XmString      message_string = NULL;
  460.   XmString      button_string = NULL;
  461.   char          text4[50];
  462.  
  463.   strcpy (text4, &ident1[4]);
  464.   /*  Generate message to display. */
  465.   sprintf (message, "This is %s \0",text4);
  466.  
  467.   /* Create the compound strings */
  468.   message_string = XmStringCreateLtoR (message, charset);
  469.   button_string = XmStringCreateLtoR ("Close", charset);
  470.   title_string = XmStringCreateLtoR ("diskuse help", charset);
  471.  
  472.  
  473.   /*  Create message box dialog. */
  474.   n = 0;
  475.   XtSetArg (args[n], XmNdialogTitle, title_string);  n++;
  476.   XtSetArg (args[n], XmNokLabelString, button_string);  n++;
  477.   XtSetArg (args[n], XmNmessageString, message_string);  n++;
  478.   message_box = XmCreateMessageDialog (parent, "versionbox", args, n);
  479.  
  480.   button = XmMessageBoxGetChild (message_box, XmDIALOG_CANCEL_BUTTON);
  481.   XtUnmanageChild (button);
  482.   button = XmMessageBoxGetChild (message_box, XmDIALOG_HELP_BUTTON);
  483.   XtUnmanageChild (button);
  484.  
  485.   /*  Free strings and return message box. */
  486.   if (title_string) XmStringFree (title_string);
  487.   if (message_string) XmStringFree (message_string);
  488.   if (button_string) XmStringFree (button_string);
  489.   return (message_box);
  490. }
  491.  
  492. /*-------------------------------------------------------------
  493. **  QuitCB      - callback for quit button
  494. */
  495. void QuitCB (w, client_data, call_data) 
  496. Widget     w;            /*  widget ID              */
  497. XtPointer  client_data;  /*  data from application  */
  498. XtPointer  call_data;    /*  data from widget class */
  499. {
  500.  
  501.   /*  Terminate the application. */
  502.   exit (0);
  503. }
  504. /***********************************************************************
  505.  ***                             MAIN                                ***
  506.  ***********************************************************************/
  507. void main(argc, argv)
  508.   unsigned int argc;
  509.   char **argv;
  510. {
  511.    Widget appshell, main_window, menu_bar, menu_pane, button, rowcol,
  512.   textf, pbutton1, pbutton2, pbutton3;
  513.    Widget bboard, labelg, cascade, form1; 
  514.    Arg args[10];
  515.    int n;
  516.    char *text1 = "Home Directory Usage";
  517.    char *text2 = "Current Directory Usage";
  518.    char *text3 = "File Space Available";
  519.    XmString label_text1;
  520.    XmString label_text2;
  521.    XmString label_text3;
  522.    XmString textf_label;
  523.      
  524. /*
  525.  * Initialize the Xt Intrinsics
  526.  */
  527.    appshell = XtAppInitialize(&app_context, "Diskuse", NULL, 0, &argc, argv,
  528.    NULL, args, 0);
  529.  
  530.   /*  Create main window.
  531.   */
  532.   n = 0;
  533.   XtSetArg (args[n], XmNshowSeparator, True);  n++;
  534.   main_window = XmCreateMainWindow (appshell, "main1", args, n);
  535.   XtManageChild (main_window);
  536.  
  537.   /*  Create menu bar in main window */
  538.   n = 0;
  539.   menu_bar = XmCreateMenuBar (main_window, "menu_bar", args, n); 
  540.   XtManageChild (menu_bar);
  541.  
  542.   /*  Create "File" pulldown menu. */
  543.   n = 0;
  544.   menu_pane = XmCreatePulldownMenu (menu_bar, "menu_pane", args, n);
  545.  
  546.   n = 0;
  547.   button = XmCreatePushButton (menu_pane, "Exit", args, n);
  548.   XtManageChild (button);
  549.   XtAddCallback (button, XmNactivateCallback, QuitCB, NULL);
  550.  
  551.   n = 0;
  552.   XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
  553.   cascade = XmCreateCascadeButton (menu_bar, "File", args, n);
  554.   XtManageChild (cascade);
  555.  
  556.   n = 0;
  557.   XtSetArg (args[n], XmNmenuHelpWidget, cascade);  n++;
  558.   XtSetValues (menu_bar, args, n);
  559.  
  560.   /*  Create "Help" pulldown menu. */
  561.   n = 0;
  562.   menu_pane = XmCreatePulldownMenu (menu_bar, "menu_pane", args, n);
  563.  
  564.   n = 0;
  565.   button = XmCreatePushButton (menu_pane, "Help", args, n);
  566.   XtManageChild (button);
  567.   XtAddCallback (button, XmNactivateCallback, HelpCB, NULL);
  568.  
  569.   n = 0;
  570.   button = XmCreatePushButton (menu_pane, "Program Version", args, n);
  571.   XtManageChild (button);
  572.   XtAddCallback (button, XmNactivateCallback, VersionCB, NULL);
  573.  
  574.   n = 0;
  575.   XtSetArg (args[n], XmNsubMenuId, menu_pane);  n++;
  576.   cascade = XmCreateCascadeButton (menu_bar, "Help", args, n);
  577.   XtManageChild (cascade);
  578.  
  579.   n = 0;
  580.   XtSetArg (args[n], XmNmenuHelpWidget, cascade);  n++;
  581.   XtSetValues (menu_bar, args, n);
  582.  
  583. /*
  584.  * Create a bulletin board widget to hold label gadget and text field
  585.  */
  586.  
  587.    n = 0;
  588.    bboard = XmCreateBulletinBoard (main_window, "bboard", args, n);
  589.    XtManageChild(bboard);
  590.  
  591. /*
  592.  * Create a label gadget
  593.  */
  594.    
  595.    textf_label = XmStringCreateLtoR ("Enter Directory Here", charset);
  596.  
  597.    n = 0;
  598.    XtSetArg(args[n], XmNx, 10); n++;
  599.    XtSetArg(args[n], XmNy, 10); n++;
  600.    XtSetArg(args[n], XmNlabelString, textf_label); n++;
  601.    labelg = XmCreateLabelGadget (bboard, "labelg", args, n);
  602.    XtManageChild(labelg);
  603.    XmStringFree(textf_label);
  604.  
  605. /*
  606.  * Create a text field widget
  607.  */
  608.  
  609.    n = 0;
  610.    XtSetArg(args[n], XmNx, 10); n++;
  611.    XtSetArg(args[n], XmNy, 40); n++;
  612.    XtSetArg (args[n], XmNcolumns, 50); n++;
  613.    textf = XmCreateTextField (bboard, "textf", args, n);
  614.    XtManageChild(textf);
  615.    XtAddCallback (textf, XmNactivateCallback, textf_activateCB, NULL);
  616.  
  617. /*
  618.  * Create a row column widget to hold the buttons
  619.  */
  620.  
  621.  n = 0;
  622.  XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
  623.  XtSetArg(args[n], XmNnumColumns, 1); n++;
  624.  rowcol = XmCreateRowColumn (main_window, "rowcol", args, n);
  625.  XtManageChild(rowcol);
  626.  
  627. /*
  628.  * Set up compound strings for button labels
  629.  */
  630.    label_text1 = XmStringCreateLtoR(text1, XmFONTLIST_DEFAULT_TAG);
  631.    label_text2 = XmStringCreateLtoR(text2, XmFONTLIST_DEFAULT_TAG);
  632.    label_text3 = XmStringCreateLtoR(text3, XmFONTLIST_DEFAULT_TAG);
  633.    
  634. /*
  635.  * Create the Pushbuttons.
  636.  */
  637.    n = 0;
  638.    XtSetArg(args[n], XmNlabelString, label_text1); n++;
  639.    pbutton1 = XmCreatePushButton(rowcol, "pbutton", args, n);
  640.    XtManageChild(pbutton1);
  641.    XtAddCallback (pbutton1, XmNarmCallback, arm1CB, NULL);
  642.  
  643.    n = 0;
  644.    XtSetArg(args[n], XmNlabelString, label_text2); n++;
  645.    pbutton2 = XmCreatePushButton(rowcol, "pbutton", args, n);
  646.    XtManageChild(pbutton2);
  647.    XtAddCallback (pbutton2, XmNarmCallback, arm2CB, NULL);
  648.  
  649.    n = 0;
  650.    XtSetArg(args[n], XmNlabelString, label_text3); n++;
  651.    pbutton3 = XmCreatePushButton(rowcol, "pbutton", args, n);
  652.    XtManageChild(pbutton3);
  653.    XtAddCallback (pbutton3, XmNarmCallback, arm3CB, NULL);
  654.  
  655.    XmStringFree(label_text1);
  656.    XmStringFree(label_text2);
  657.    XmStringFree(label_text3);
  658.  
  659. /*
  660.  * Create a form widget for error message
  661.  */
  662.  n = 0;
  663.  form1 = XmCreateForm (main_window, "form1", args, n);
  664.  XtManageChild (form1);
  665.  
  666. /*
  667.  * Create a  label gadget within the form for error message
  668.  */
  669.  label_text1 = XmStringCreateLtoR("Error Message Window", charset);
  670.  n = 0;
  671.  XtSetArg(args[n], XmNlabelString, label_text1); n++;
  672.  XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  673.  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  674.  errmsg_box = XmCreateLabelGadget (form1, "errmsg_box", args, n);
  675.  XtManageChild(errmsg_box);
  676.  XmStringFree(label_text1);
  677.  
  678. /*
  679.  * Create a  pushbutton within the form to remove error message
  680.  */
  681.  label_text1 = XmStringCreateLtoR("Continue", charset);
  682.  n = 0;
  683.  XtSetArg(args[n], XmNlabelString, label_text1); n++;
  684.  XtSetArg (args[n], XmNtopWidget, errmsg_box); n++;
  685.  XtSetArg (args[n], XmNtopOffset, 20); n++;
  686.  XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  687.  XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  688.  XtSetArg (args[n], XmNleftOffset, 210); n++;
  689.  pbg = XmCreatePushButton (form1, "pbg", args, n);
  690.  
  691.  XtAddCallback (pbg, XmNactivateCallback, errorCB, NULL);
  692.  XmStringFree (label_text1);
  693.  
  694. /*  Set main window areas  */
  695.   XmMainWindowSetAreas (main_window, menu_bar, bboard, NULL, NULL,
  696.       rowcol);
  697.  
  698. /*Add Message Area in main window */
  699.   n = 0;
  700.   XtSetArg (args[n], XmNmessageWindow, (XtArgVal) form1); n++;
  701.   XtSetValues (main_window, args, n);
  702.  
  703. /*
  704.  * Realize the appshell widget, which displays all children
  705.  */ 
  706.    XtRealizeWidget(appshell);
  707.  
  708. /*
  709.  * Go into a loop and wait for input
  710.  */
  711.    XtAppMainLoop(app_context);
  712. }
  713.