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