home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xman / buttons.c.orig < prev    next >
Encoding:
Text File  |  1991-07-21  |  21.1 KB  |  738 lines

  1. /*
  2.  * xman - X window system manual page display program.
  3.  *
  4.  * $XConsortium: buttons.c,v 1.31 91/07/21 20:37:20 converse Exp $
  5.  *
  6.  * Copyright 1987, 1988 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:    Chris D. Peterson, MIT Project Athena
  19.  * Created:   October 27, 1987
  20.  */
  21.  
  22. #include "globals.h"
  23.  
  24. /* The files with the icon bits in them. */
  25.  
  26. #include "icon_open.h"
  27. #include "icon_help.h"
  28. #include "iconclosed.h"
  29.  
  30. static void CreateOptionMenu(), CreateSectionMenu();
  31. static void StartManpage();
  32. static Widget * ConvertNamesToWidgets();
  33. ManpageGlobals * InitPsuedoGlobals();
  34.  
  35. /*    Function Name: MakeTopBox
  36.  *    Description: This funtion creates the top menu, in a shell widget.
  37.  *    Arguments: none.
  38.  *    Returns: the top level widget
  39.  */
  40.  
  41. #define TOPARGS 5
  42.  
  43. static Atom wm_delete_window;
  44.  
  45. Widget top;            /* needed in PopupWarning, misc.c */
  46.  
  47. void
  48. MakeTopBox()
  49. {
  50.   Widget form, command, label; /* widgets. */
  51.   Arg arglist[TOPARGS];        /* An argument list */
  52.   Cardinal num_args = 0;    /* The number of arguments. */
  53.   ManpageGlobals * man_globals;
  54.   static char * full_size[] = {
  55.     "topLabel", MANPAGE_BUTTON, NULL
  56.   };
  57.   static char * half_size[] = {
  58.     HELP_BUTTON, QUIT_BUTTON, NULL
  59.   };
  60.   
  61. /* create the top icon. */
  62.  
  63.   num_args = 0;
  64.   XtSetArg(arglist[num_args], XtNiconPixmap,
  65.        XCreateBitmapFromData( XtDisplay(initial_widget), 
  66.                  XtScreen(initial_widget)->root,
  67.                  (char *)iconclosed_bits, iconclosed_width,
  68.                  iconclosed_height));
  69.   num_args++;
  70.   XtSetArg(arglist[num_args], XtNtitle, resources.title);
  71.   num_args++;
  72.   XtSetArg(arglist[num_args], XtNiconic, resources.iconic);
  73.   num_args++;
  74.   top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass, 
  75.                initial_widget, arglist, num_args);
  76.  
  77.   form = XtCreateManagedWidget("form", formWidgetClass, top, 
  78.                    NULL, (Cardinal) 0);
  79.  
  80.   label = XtCreateManagedWidget("topLabel", labelWidgetClass, form, 
  81.                    NULL, (Cardinal) 0);
  82.  
  83.   num_args = 0;
  84.   XtSetArg(arglist[num_args], XtNfromVert, label); num_args++;
  85.   command = XtCreateManagedWidget(HELP_BUTTON, commandWidgetClass, form, 
  86.                   arglist, num_args);
  87.  
  88.   /* use same vertical as help widget. */
  89.   XtSetArg(arglist[num_args], XtNfromHoriz, command); num_args++;
  90.   command = XtCreateManagedWidget(QUIT_BUTTON, commandWidgetClass, form, 
  91.                   arglist, num_args);
  92.  
  93.   num_args = 0;
  94.   XtSetArg(arglist[num_args], XtNfromVert, command); num_args++;
  95.   command = XtCreateManagedWidget(MANPAGE_BUTTON, commandWidgetClass, form, 
  96.                   arglist, num_args);
  97.  
  98.   help_widget = NULL;        /* We have not seen the help yet. */
  99.  
  100.   FormUpWidgets(form, full_size, half_size);
  101.  
  102.   XtRealizeWidget(top);
  103.   man_globals = (ManpageGlobals*) XtMalloc( (Cardinal) sizeof(ManpageGlobals));
  104.   man_globals->label = NULL;
  105.   man_globals->manpagewidgets.directory = NULL;
  106.   man_globals->manpagewidgets.manpage = NULL;
  107.   man_globals->manpagewidgets.box = NULL;
  108.   man_globals->current_directory = 0;
  109.   MakeSearchWidget(man_globals, top);
  110.   MakeSaveWidgets(man_globals, top);
  111.  
  112.   SaveGlobals( (man_globals->This_Manpage = top), man_globals);
  113.   XtMapWidget(top);
  114.   AddCursor(top, resources.cursors.top);
  115.  
  116. /*
  117.  * Set up ICCCM delete window.
  118.  */
  119.   wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW",
  120.                  False);
  121.   XtOverrideTranslations
  122.       (top, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
  123.   (void) XSetWMProtocols (XtDisplay(top), XtWindow(top),
  124.               &wm_delete_window, 1);
  125.   
  126.  
  127. }
  128.  
  129. /*    Function Name: CreateManpage
  130.  *    Description: Creates a new manpage.
  131.  *    Arguments: none.
  132.  *    Returns: none.
  133.  */
  134.  
  135. Widget
  136. CreateManpage( file )
  137. FILE * file;
  138. {
  139.   ManpageGlobals * man_globals;    /* The psuedo global structure. */
  140.  
  141.   man_globals = InitPsuedoGlobals();
  142.   CreateManpageWidget(man_globals, MANNAME, TRUE);
  143.   
  144.   if (file == NULL)
  145.     StartManpage( man_globals, OpenHelpfile(man_globals), FALSE );
  146.   else {
  147.     OpenFile(man_globals, file);
  148.     StartManpage( man_globals, FALSE, TRUE);
  149.   }
  150.   return(man_globals->This_Manpage);
  151. }
  152.  
  153. /*    Function Name: InitPsuedoGlobals
  154.  *    Description: Initializes the psuedo global variables.
  155.  *    Arguments: none.
  156.  *    Returns: a pointer to a new pseudo globals structure.
  157.  */
  158.  
  159. ManpageGlobals * 
  160. InitPsuedoGlobals()
  161. {
  162.   ManpageGlobals * man_globals;
  163.  
  164.   /*
  165.    * Allocate necessary memory. 
  166.    */
  167.  
  168.   man_globals = (ManpageGlobals *) 
  169.                 XtMalloc( (Cardinal) sizeof(ManpageGlobals));
  170.  
  171.   man_globals->section_name = (char **) XtMalloc( (Cardinal) (sections *
  172.                                   sizeof(char *)));
  173.   man_globals->manpagewidgets.box = (Widget *) XtCalloc( (Cardinal) sections,
  174.                             (Cardinal) sizeof(Widget));
  175.   
  176.   /* Initialize the number of screens that will be shown */
  177.  
  178.   man_globals->both_shown = resources.both_shown_initial;
  179.   
  180.   return(man_globals);
  181. }
  182.   
  183. /*    Function Name: CreateManpageWidget
  184.  *    Description: Creates a new manual page widget.
  185.  *    Arguments: man_globals - a new man_globals structure.
  186.  *                 name         - name of this shell widget instance.
  187.  *                 full_instance - if true then create a full manpage,
  188.  *                                 otherwise create stripped down version
  189.  *                                 used for help.
  190.  *    Returns: none
  191.  */
  192.  
  193. #define MANPAGEARGS 10
  194.  
  195. void
  196. CreateManpageWidget(man_globals, name, full_instance)
  197. ManpageGlobals * man_globals;
  198. char * name;
  199. Boolean full_instance;
  200. {
  201.   Arg arglist[MANPAGEARGS];    /* An argument list for widget creation */
  202.   Cardinal num_args;        /* The number of arguments in the list. */
  203.   Widget top, pane, hpane, sections;    /* Widgets */
  204.   ManPageWidgets * mpw = &(man_globals->manpagewidgets);
  205.  
  206.   num_args = (Cardinal) 0;
  207.   XtSetArg(arglist[num_args], XtNwidth, default_width);
  208.   num_args++; 
  209.   XtSetArg(arglist[num_args], XtNheight, default_height);
  210.   num_args++; 
  211.  
  212.   top = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget,
  213.                arglist, num_args);
  214.  
  215.   man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
  216.   num_args = 0;
  217.   if (full_instance)
  218.     XtSetArg(arglist[num_args], XtNiconPixmap,
  219.          XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
  220.                    (char *)icon_open_bits, icon_open_width,
  221.                    icon_open_height));
  222.   else 
  223.     XtSetArg(arglist[num_args], XtNiconPixmap,
  224.          XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
  225.                    (char *)icon_help_bits, icon_help_width,
  226.                    icon_help_height));
  227.   num_args++;
  228.   XtSetValues(top, arglist, num_args);
  229.  
  230.   pane = XtCreateManagedWidget("Manpage_Vpane", panedWidgetClass, top, NULL, 
  231.                    (Cardinal) 0);
  232.  
  233. /* Create menu bar. */
  234.  
  235.   hpane = XtCreateManagedWidget("horizPane", panedWidgetClass,
  236.                   pane, NULL, (Cardinal) 0);
  237.   num_args = 0;
  238.   XtSetArg(arglist[num_args], XtNmenuName, OPTION_MENU); num_args++;
  239.   (void) XtCreateManagedWidget("options", menuButtonWidgetClass,
  240.                   hpane, arglist, num_args);
  241.  
  242.   CreateOptionMenu(man_globals, top);
  243.  
  244.   num_args = 0;
  245.   XtSetArg(arglist[num_args], XtNmenuName, SECTION_MENU); num_args++;
  246.   sections = XtCreateManagedWidget("sections", menuButtonWidgetClass,
  247.                    hpane, arglist, num_args);
  248.  
  249.   XtSetArg(arglist[0], XtNlabel, SHOW_BOTH);
  250.   XtSetValues(man_globals->both_screens_entry, arglist, (Cardinal) 1);
  251.  
  252.   if (full_instance) {
  253.     MakeSearchWidget(man_globals, top);
  254.     CreateSectionMenu(man_globals, top);
  255.     MakeSaveWidgets(man_globals, top);
  256.   } else {
  257.     XtSetSensitive(sections, FALSE);       
  258.     XtSetArg(arglist[0], XtNsensitive, FALSE);
  259.     XtSetValues(man_globals->dir_entry, arglist, ONE);
  260.     XtSetValues(man_globals->manpage_entry, arglist, ONE);
  261.     XtSetValues(man_globals->help_entry, arglist, ONE);
  262.     XtSetValues(man_globals->search_entry, arglist, ONE);
  263.     XtSetValues(man_globals->both_screens_entry, arglist, ONE);
  264.   }
  265.  
  266.   man_globals->label = XtCreateManagedWidget(MANNAME, labelWidgetClass,
  267.                          hpane, NULL, (Cardinal) 0);
  268.  
  269. /* Create Directory */
  270.  
  271.   if (full_instance) {
  272.     num_args = 0;
  273.     XtSetArg(arglist[num_args], XtNallowVert, TRUE);
  274.     num_args++;
  275.     
  276.     mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  277.                     pane, arglist, num_args);
  278.     
  279.     man_globals->current_directory = INITIAL_DIR;
  280.     MakeDirectoryBox(man_globals, mpw->directory,
  281.              mpw->box + man_globals->current_directory, 
  282.              man_globals->current_directory );
  283.     XtManageChild(mpw->box[man_globals->current_directory]);
  284.   }
  285.  
  286. /* Create Manpage */
  287.  
  288.   mpw->manpage = XtCreateWidget(MANUALPAGE, scrollByLineWidgetClass,
  289.                 pane, NULL, (Cardinal) 0);
  290.  
  291. }
  292.  
  293. /*    Function Name: StartManpage
  294.  *    Description: Starts up a new manpage.
  295.  *    Arguments: man_globals - the psuedo globals variable.
  296.  *                 help - is this a help file?
  297.  *                 page - Is there a page to display?
  298.  *    Returns: none.
  299.  */
  300.  
  301. static void
  302. StartManpage(man_globals, help, page)
  303. ManpageGlobals * man_globals;
  304. Boolean help, page;
  305. {
  306.   Widget dir = man_globals->manpagewidgets.directory;
  307.   Widget manpage = man_globals->manpagewidgets.manpage;
  308.   Widget label = man_globals->label;
  309.   Arg arglist[1];
  310.  
  311. /* 
  312.  * If there is a helpfile then put up both screens if both_show is set.
  313.  */
  314.  
  315.   if (page || help) {
  316.     if (help) 
  317.       strcpy(man_globals->manpage_title, "Xman Help");
  318.  
  319.     if (man_globals->both_shown) {
  320.       XtManageChild(dir);
  321.       man_globals->dir_shown = TRUE;
  322.  
  323.       XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height);
  324.       XtSetValues(dir, arglist, (Cardinal) 1);
  325.  
  326.       XtSetArg(arglist[0], XtNsensitive, FALSE);
  327.       XtSetValues(man_globals->manpage_entry, arglist, ONE);
  328.       XtSetValues(man_globals->dir_entry, arglist, ONE);
  329.  
  330.       XtSetArg(arglist[0], XtNlabel, SHOW_ONE);
  331.       XtSetValues(man_globals->both_screens_entry, arglist, ONE);
  332.       ChangeLabel(label,
  333.           man_globals->section_name[man_globals->current_directory]);
  334.     }
  335.     else {
  336.       ChangeLabel(label,man_globals->manpage_title);
  337.     }
  338.     XtManageChild(manpage);
  339.     man_globals->dir_shown = FALSE;
  340.   }
  341. /*
  342.  * Since There is file to display, put up directory and do not allow change
  343.  * to manpage, show both, or help.
  344.  */
  345.   else {            
  346.     XtManageChild(dir);
  347.     man_globals->dir_shown = TRUE;
  348.     XtSetArg(arglist[0], XtNsensitive, FALSE);
  349.     XtSetValues(man_globals->manpage_entry,        arglist, ONE);
  350.     XtSetValues(man_globals->help_entry,           arglist, ONE);
  351.     XtSetValues(man_globals->both_screens_entry,   arglist, ONE);
  352.     man_globals->both_shown = FALSE;
  353.     ChangeLabel(label,
  354.         man_globals->section_name[man_globals->current_directory]);
  355.   }
  356.  
  357. /*
  358.  * Start 'er up, and change the cursor.
  359.  */
  360.  
  361.   XtRealizeWidget( man_globals->This_Manpage );
  362.   SaveGlobals( man_globals->This_Manpage, man_globals);
  363.   XtMapWidget( man_globals->This_Manpage );
  364.   AddCursor( man_globals->This_Manpage, resources.cursors.manpage);
  365.   XtSetArg(arglist[0], XtNtransientFor, man_globals->This_Manpage);
  366.   XtSetValues(XtParent(man_globals->standby), arglist, (Cardinal)1);
  367.   XtSetValues(XtParent(man_globals->save), arglist, (Cardinal) 1);
  368.   XtRealizeWidget(XtParent(man_globals->standby));
  369.   XtRealizeWidget(XtParent(man_globals->save));
  370.   AddCursor( XtParent(man_globals->standby), resources.cursors.top);
  371.   AddCursor( XtParent(man_globals->save), resources.cursors.top);
  372.  
  373. /*
  374.  * Set up ICCCM delete window.
  375.  */
  376.   XtOverrideTranslations
  377.       (man_globals->This_Manpage, 
  378.        XtParseTranslationTable ("<Message>WM_PROTOCOLS: RemoveThisManpage()"));
  379.   (void) XSetWMProtocols (XtDisplay(man_globals->This_Manpage),
  380.               XtWindow(man_globals->This_Manpage),
  381.               &wm_delete_window, 1);
  382.  
  383. }
  384.  
  385. /*      Function Name: MenuDestroy
  386.  *      Description: free's data associated with menu when it is destroyed.
  387.  *      Arguments: w - menu widget.
  388.  *                 free_me - data to free.
  389.  *                 junk - not used.
  390.  *      Returns: none.
  391.  */
  392.  
  393. /* ARGSUSED */
  394. static void
  395. MenuDestroy(w, free_me, junk)
  396. Widget w;
  397. XtPointer free_me, junk;
  398. {
  399.   XtFree( (char *) free_me);
  400. }
  401.  
  402. /*      Function Name:   CreateOptionMenu
  403.  *      Description: Create the option menu.
  404.  *      Arguments: man_globals - the manual page globals.
  405.  *                 parent - the button that activates the menu.
  406.  *      Returns: none.
  407.  */
  408.  
  409. static void
  410. CreateOptionMenu(man_globals, parent)
  411. ManpageGlobals * man_globals;
  412. Widget parent;
  413. {
  414.   Widget menu, entry;
  415.   int i;
  416.   static char * option_names[] = {    /* Names of the buttons. */
  417.     DIRECTORY,
  418.     MANPAGE,
  419.     HELP,
  420.     SEARCH,
  421.     BOTH_SCREENS, 
  422.     REMOVE_MANPAGE,
  423.     OPEN_MANPAGE,
  424.     SHOW_VERSION,
  425.     QUIT
  426.   };
  427.  
  428.   menu = XtCreatePopupShell(OPTION_MENU, simpleMenuWidgetClass, parent,
  429.                 NULL, (Cardinal) 0);
  430.   man_globals->option_menu = menu;
  431.   
  432.   for (i = 0 ; i < NUM_OPTIONS ; i++) {
  433.     entry = XtCreateManagedWidget(option_names[i], smeBSBObjectClass,
  434.                   menu, NULL, ZERO);
  435.     XtAddCallback(entry, XtNcallback, OptionCallback, (caddr_t) man_globals);
  436.     switch (i) {
  437.     case 0:
  438.     man_globals->dir_entry = entry;
  439.     break;
  440.     case 1:
  441.     man_globals->manpage_entry = entry;
  442.     break;
  443.     case 2:
  444.     man_globals->help_entry = entry;
  445.     break;
  446.     case 3:
  447.     man_globals->search_entry = entry;
  448.     break;
  449.     case 4:
  450.     man_globals->both_screens_entry = entry;
  451.     break;
  452.     case 5:
  453.     man_globals->remove_entry = entry;
  454.     break;
  455.     case 6:
  456.     man_globals->open_entry = entry;
  457.     break;
  458.     case 7:
  459.     man_globals->version_entry = entry;
  460.     break;
  461.     case 8:
  462.     man_globals->quit_entry = entry;
  463.     break;
  464.     default:
  465.     break;
  466.     }
  467.   }
  468. }
  469.  
  470. /*      Function Name: CreateSectionMenu
  471.  *      Description: Create the Section menu.
  472.  *      Arguments: man_globals - the manual page globals.
  473.  *                 parent - the button that activates the menu.
  474.  *      Returns: none.
  475.  */
  476.  
  477. static void
  478. CreateSectionMenu(man_globals, parent)
  479. ManpageGlobals * man_globals;
  480. Widget parent;
  481. {
  482.   Widget menu, entry;
  483.   int i;
  484.   MenuStruct * menu_struct;
  485.   Arg args[1];
  486.   Cardinal num_args;
  487.   char entry_name[BUFSIZ];
  488.  
  489.   menu = XtCreatePopupShell(SECTION_MENU, simpleMenuWidgetClass, parent,
  490.                 NULL, (Cardinal) 0);
  491.  
  492.   for (i = 0 ; i < sections ; i ++) {
  493.     num_args = 0;
  494.     XtSetArg(args[num_args], XtNlabel, manual[i].blabel); num_args++;
  495.     sprintf(entry_name, "section%d", i);
  496.       
  497.     entry = XtCreateManagedWidget(entry_name, smeBSBObjectClass,
  498.                   menu, args, num_args);
  499.     menu_struct = (MenuStruct *) XtMalloc(sizeof(MenuStruct));
  500.     menu_struct->data = (caddr_t) man_globals;
  501.     menu_struct->number = i;
  502.     XtAddCallback(entry, XtNcallback, DirPopupCallback, (caddr_t) menu_struct);
  503.     XtAddCallback(entry, XtNdestroyCallback,MenuDestroy, (caddr_t)menu_struct);
  504.  
  505.   }
  506. }
  507.  
  508. /*    Function Name: CreateList
  509.  *    Description: this function prints a label in the directory list
  510.  *    Arguments: section - the manual section.
  511.  *    Returns: none
  512.  */
  513.  
  514. static char **
  515. CreateList(section)
  516. {
  517.   char ** ret_list, **current;
  518.   int count;
  519.  
  520.   ret_list = (char **) XtMalloc( (manual[section].nentries + 1) * 
  521.                    sizeof (char *));
  522.  
  523.   for (current = ret_list, count = 0 ; count < manual[section].nentries ;
  524.        count++, current++)
  525.     *current = CreateManpageName(manual[section].entries[count], section,
  526.                  manual[section].flags);
  527.  
  528.   *current = NULL;        /* NULL terminate the list. */
  529.   return(ret_list);
  530. }
  531.  
  532. /*    Function Name: MakeDirectoryBox
  533.  *    Description: make a directory box.
  534.  *    Arguments: man_globals - the psuedo global structure for each manpage.
  535.  *                 parent - this guys parent widget.
  536.  *                 dir_disp - the directory display widget.
  537.  *                 section - the section number.
  538.  *    Returns: none.
  539.  */
  540.  
  541. void
  542. MakeDirectoryBox(man_globals,parent,dir_disp,section)
  543. ManpageGlobals *man_globals;
  544. Widget parent, *dir_disp;
  545. int section;
  546. {
  547.   Arg arglist[10];
  548.   Cardinal num_args;
  549.   char * name, label_name[BUFSIZ];
  550.  
  551.   if (*dir_disp != NULL)    /* If we have one, don't make another. */
  552.     return;
  553.  
  554.   name = manual[section].blabel;   /* Set the section name */
  555.   sprintf(label_name,"Directory of: %s",name);
  556.   man_globals->section_name[section] = StrAlloc(label_name);
  557.  
  558.   num_args = 0;
  559.   XtSetArg(arglist[num_args], XtNlist, CreateList(section));
  560.   num_args++;
  561.   XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory);
  562.   num_args++;
  563.   
  564.   *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
  565.                  arglist, num_args);
  566.   
  567.   XtAddCallback(*dir_disp, XtNcallback,
  568.         DirectoryHandler, (caddr_t) man_globals);
  569. }
  570.  
  571. /*    Function Name: MakeSaveWidgets.
  572.  *    Description: This functions creates two popup widgets, the please 
  573.  *                   standby widget and the would you like to save widget.
  574.  *    Arguments: man_globals - the psuedo globals structure for each man page
  575.  *                 parent - the realized parent for both popups.
  576.  *    Returns: none.
  577.  */
  578.  
  579. void
  580. MakeSaveWidgets(man_globals, parent)
  581. ManpageGlobals *man_globals;
  582. Widget parent;
  583. {
  584.   Widget shell, dialog; /* misc. widgets. */
  585.   Arg warg[1];
  586.   Cardinal n = 0;
  587.  
  588. /* make the please stand by popup widget. */
  589.   if (XtIsRealized(parent)) {
  590.       XtSetArg(warg[0], XtNtransientFor, parent);    n++;
  591.   }
  592.   shell = XtCreatePopupShell( "pleaseStandBy", transientShellWidgetClass,
  593.                   parent, warg, (Cardinal) n);
  594.  
  595.   man_globals->standby = XtCreateManagedWidget("label", labelWidgetClass, 
  596.                            shell, NULL, (Cardinal) 0);
  597.  
  598.   man_globals->save = XtCreatePopupShell("likeToSave",
  599.                      transientShellWidgetClass,
  600.                      parent, warg, n);
  601.  
  602.   dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, 
  603.                  man_globals->save, NULL, (Cardinal) 0);
  604.  
  605.   XawDialogAddButton(dialog, FILE_SAVE, NULL, NULL);
  606.   XawDialogAddButton(dialog, CANCEL_FILE_SAVE, NULL, NULL);
  607.  
  608.   if (XtIsRealized(parent)) {
  609.       XtRealizeWidget(shell);
  610.       AddCursor(shell,resources.cursors.top);
  611.       XtRealizeWidget(man_globals->save);
  612.       AddCursor(man_globals->save, resources.cursors.top);
  613.   }
  614. }
  615.  
  616. /*      Function Name: FormUpWidgets
  617.  *      Description: Sizes widgets to look nice.
  618.  *      Arguments: parent - the common parent of all the widgets.
  619.  *                 full_size - array of widget names that will he full size.
  620.  *                 half_size - array of widget names that will he half size.
  621.  *      Returns: none
  622.  */
  623.  
  624. void
  625. FormUpWidgets(parent, full_size, half_size)
  626. Widget parent;
  627. char ** full_size, ** half_size;
  628. {
  629.   Widget * full_widgets, * half_widgets, *temp, long_widget;
  630.   Dimension longest, length, b_width;
  631.   int interior_dist;
  632.   Arg arglist[2];
  633.     
  634.   full_widgets = ConvertNamesToWidgets(parent, full_size);
  635.   half_widgets = ConvertNamesToWidgets(parent, half_size);
  636.   
  637.   long_widget = NULL;
  638.   longest = 0;
  639.   XtSetArg(arglist[0], XtNwidth, &length);
  640.   XtSetArg(arglist[1], XtNborderWidth, &b_width);
  641.  
  642. /*
  643.  * Find Longest widget.
  644.  */
  645.  
  646.   for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++) {
  647.     XtGetValues(*temp, arglist, (Cardinal) 2);
  648.     length += 2 * b_width;
  649.     if (length > longest) {
  650.       longest = length;
  651.       long_widget = *temp;
  652.     }
  653.   }
  654.  
  655.   if (long_widget == (Widget) NULL) {          /* Make sure we found one. */
  656.     PopupWarning(GetGlobals(parent), 
  657.          "Could not find longest widget, aborting...");
  658.     XtFree((char *)full_widgets);
  659.     XtFree((char *)half_widgets);
  660.     return;
  661.   }
  662.  
  663. /*
  664.  * Set all other full_widgets to this length.
  665.  */
  666.  
  667.   for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++ )
  668.     if ( long_widget != *temp) {
  669.       Dimension width, border_width;
  670.  
  671.       XtSetArg(arglist[0], XtNborderWidth, &border_width);
  672.       XtGetValues(*temp, arglist, (Cardinal) 1);
  673.     
  674.       width = longest - 2 * border_width;
  675.       XtSetArg(arglist[0], XtNwidth, width);
  676.       XtSetValues(*temp, arglist, (Cardinal) 1);
  677.     }
  678.  
  679. /*
  680.  * Set all the half widgets to the right length.
  681.  */
  682.  
  683.   XtSetArg(arglist[0], XtNdefaultDistance, &interior_dist);
  684.   XtGetValues(parent, arglist, (Cardinal) 1);
  685.   
  686.   for ( temp = half_widgets ; *temp != (Widget) NULL ; temp++) {
  687.     Dimension width, border_width;
  688.  
  689.     XtSetArg(arglist[0], XtNborderWidth, &border_width);
  690.     XtGetValues(*temp, arglist, (Cardinal) 1);
  691.     
  692.     width = (int)(longest - interior_dist)/2 - 2 * border_width;
  693.     XtSetArg(arglist[0], XtNwidth, width);
  694.     XtSetValues(*temp, arglist, (Cardinal) 1);
  695.   }
  696.  
  697.   XtFree((char *)full_widgets);
  698.   XtFree((char *)half_widgets);
  699. }
  700.   
  701. /*      Function Name: ConvertNamesToWidgets
  702.  *      Description: Convers a list of names into a list of widgets.
  703.  *      Arguments: parent - the common parent of these widgets.
  704.  *                 names - an array of widget names.
  705.  *      Returns: an array of widget id's.
  706.  */
  707.  
  708. static Widget *
  709. ConvertNamesToWidgets(parent, names)
  710. Widget parent;
  711. char ** names;
  712. {
  713.   char ** temp;
  714.   Widget * ids, * temp_ids;
  715.   int count;
  716.  
  717.   for (count = 0, temp = names; *temp != NULL ; count++, temp++);
  718.  
  719.   ids = (Widget *) XtMalloc( (count + 1) * sizeof(Widget));
  720.  
  721.   
  722.   for ( temp_ids = ids; *names != NULL ; names++, temp_ids++) {
  723.     *temp_ids = XtNameToWidget(parent, *names);
  724.     if (*temp_ids == NULL) {
  725.       char error_buf[BUFSIZ];
  726.     
  727.       sprintf(error_buf, "Could not find widget named '%s'", *names);
  728.       PrintError(error_buf);
  729.       XtFree((char *)ids);
  730.       return(NULL);
  731.     }
  732.   }
  733.   
  734.   *temp_ids = (Widget) NULL;
  735.   return(ids);
  736. }
  737.     
  738.