buttons.c revision ae5a67ad
1/* 2 3Copyright (c) 1987, 1988 X Consortium 4 5Permission is hereby granted, free of charge, to any person obtaining 6a copy of this software and associated documentation files (the 7"Software"), to deal in the Software without restriction, including 8without limitation the rights to use, copy, modify, merge, publish, 9distribute, sublicense, and/or sell copies of the Software, and to 10permit persons to whom the Software is furnished to do so, subject to 11the following conditions: 12 13The above copyright notice and this permission notice shall be included 14in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR 20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of the X Consortium shall 25not be used in advertising or otherwise to promote the sale, use or 26other dealings in this Software without prior written authorization 27from 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 46static void CreateOptionMenu(ManpageGlobals * man_globals, Widget parent); 47static void CreateSectionMenu(ManpageGlobals * man_globals, Widget parent); 48static void StartManpage(ManpageGlobals * man_globals, Boolean help, 49 Boolean page); 50static 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 60Widget top; /* needed in PopupWarning, misc.c */ 61 62void 63MakeTopBox(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 148Widget 149CreateManpage(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 173ManpageGlobals * 174InitPsuedoGlobals(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 213void 214CreateManpageWidget(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 325static void 326StartManpage(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 */ 418static void 419MenuDestroy(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 431static void 432CreateOptionMenu(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 518static void 519CreateSectionMenu(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 556static char ** 557CreateList(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 583void 584MakeDirectoryBox(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 619void 620MakeSaveWidgets(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 663void 664FormUpWidgets(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 745static Widget * 746ConvertNamesToWidgets(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