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