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