widgets.c revision 352bf44e
1/* 2 * 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 */ 25 26/* 27 * Code for creating all widgets used by EditRes. 28 */ 29 30#include <stdio.h> 31#include <X11/Intrinsic.h> 32#include <X11/StringDefs.h> /* Get standard string definitions. */ 33 34#include <X11/Xaw/AsciiText.h> 35#include <X11/Xaw/Box.h> 36#include <X11/Xaw/Cardinals.h> 37#include <X11/Xaw/Label.h> 38#include <X11/Xaw/List.h> 39#include <X11/Xaw/MenuButton.h> 40#include <X11/Xaw/Paned.h> 41#include <X11/Xaw/Panner.h> 42#include <X11/Xaw/Porthole.h> 43#include <X11/Xaw/SmeBSB.h> 44#include <X11/Xaw/SmeLine.h> 45#include <X11/Xaw/SimpleMenu.h> 46#include <X11/Xaw/Toggle.h> 47#include <X11/Xaw/Tree.h> 48#include <X11/Xaw/Viewport.h> 49 50#include "editresP.h" 51 52 53 54/* 55 * functions. 56 */ 57 58static Widget CreateTopArea ( Widget parent ); 59static void CreateCommandMenu ( Widget parent, String toolkit ); 60static void CreateTreeCommandMenu ( Widget parent, String toolkit ); 61static void CreateResourceNameForm ( Widget parent, WNode * node ); 62static void SetToggleGroupLeaders ( WNode * node ); 63static void MakeBoxLookNice ( Widget dot, Widget star, Widget any, 64 Widget single, Widget name, Widget class, 65 int endbox ); 66static void CreateLists ( Widget parent, WNode * node, char **names, 67 char **cons_names ); 68static void CreateValueWidget ( Widget parent, WNode * node ); 69static void PopupOnNode ( WNode * node, Widget shell ); 70static void FreeClientData ( Widget w, XtPointer ptr, XtPointer junk ); 71static void FreeResBox ( Widget w, XtPointer ptr, XtPointer junk ); 72 73 74 75/* Function Name: RebuildMenusAndLabel 76 * Description: Determines if the user has selected an application 77 * which uses a different toolkit. Xt is the default. 78 * If this is so, destroys and recreates the menus and 79 * information label at the top of the application. 80 * Arguments: toolkit - name of the toolkit. 81 * Returns: none. 82 */ 83 84static Widget box = NULL; 85static Widget hPane = NULL; 86 87#define Offset(index) sizeof(String) * index 88 89#define res_entry(index, name, class) \ 90 {name, class, XtRString, sizeof(String), \ 91 Offset(index), XtRString, (XtPointer)NULL} 92 93static XtResource resources[] = { 94 res_entry(0, "label0", "Label0"), 95 res_entry(1, "label1", "Label1"), 96 res_entry(2, "label2", "Label2"), 97 res_entry(3, "label3", "Label3"), 98 res_entry(4, "label4", "Label4"), 99 res_entry(5, "label5", "Label5"), 100 res_entry(6, "label6", "Label6"), 101 res_entry(7, "label7", "Label7"), 102 res_entry(8, "label8", "Label8"), 103 res_entry(9, "label9", "Label9"), 104 res_entry(11, "label11", "Label11"), 105 res_entry(12, "label12", "Label12"), 106 res_entry(13, "label13", "Label13"), 107 res_entry(14, "label14", "Label14"), 108 res_entry(15, "label15", "Label15"), 109 res_entry(16, "label16", "Label16"), 110 res_entry(17, "label17", "Label17"), 111 res_entry(18, "label18", "Label18"), 112 res_entry(19, "label19", "Label19"), 113 res_entry(20, "label20", "Label20"), 114 res_entry(21, "label21", "Label21"), 115 res_entry(22, "label22", "Label22"), 116 res_entry(23, "label23", "Label23"), 117 res_entry(24, "label24", "Label24"), 118 res_entry(25, "label25", "Label25"), 119 res_entry(26, "label26", "Label26"), 120 res_entry(27, "label27", "Label27"), 121 res_entry(28, "label28", "Label28"), 122 res_entry(29, "label29", "Label29"), 123 res_entry(30, "label30", "Label30"), 124 res_entry(31, "label31", "Label31"), 125 res_entry(32, "label32", "Label32"), 126 res_entry(33, "label33", "Label33"), 127 res_entry(34, "label34", "Label34"), 128 res_entry(35, "label35", "Label35"), 129 res_entry(36, "label36", "Label36") 130}; 131 132#undef res_entry 133 134#undef Offset 135 136void 137RebuildMenusAndLabel(String toolkit) 138{ 139 if (strcmp(global_effective_toolkit, toolkit)) { 140 CreateCommandMenu(box, toolkit); 141 CreateTreeCommandMenu(box, toolkit); 142 XtDestroyWidget(global_screen_data.info_label); 143 global_screen_data.info_label = XtCreateManagedWidget(toolkit, 144 labelWidgetClass, 145 hPane, NULL, ZERO); 146 /* get the new toolkit label application resources for info_label */ 147 XtGetApplicationResources(global_screen_data.info_label, 148 res_labels, resources, 149 XtNumber(resources), NULL, 0); 150 151 global_effective_toolkit = toolkit; 152 } 153} 154 155 156 157/* Function Name: BuildWidgetTree 158 * Description: Creates all widgets for Editres. 159 * Arguments: parent - the shell to put them into. 160 * Returns: none. 161 */ 162 163void 164BuildWidgetTree(Widget parent) 165{ 166 Widget paned, porthole, panner; 167 168 paned = XtCreateManagedWidget("paned", panedWidgetClass, parent, 169 NULL, ZERO); 170 171 panner = CreateTopArea(paned); 172 173 porthole = XtCreateManagedWidget("porthole", portholeWidgetClass, 174 paned, NULL, ZERO); 175 176/* 177 * Allow the panner and porthole to talk to each other. 178 */ 179 180 XtAddCallback(porthole, 181 XtNreportCallback, PortholeCallback, (XtPointer) panner); 182 XtAddCallback(panner, 183 XtNreportCallback, PannerCallback, (XtPointer) porthole); 184 185 global_tree_parent = porthole; 186} 187 188 189 190 191/* Function Name: CreateTopArea 192 * Description: Creates the top part of the display 193 * Arguments: parent - widget to put this menu bar into. 194 * Returns: none. 195 */ 196 197 198static Widget 199CreateTopArea(Widget parent) 200{ 201 Widget panner; 202 203 box = XtCreateManagedWidget("box", boxWidgetClass, parent, NULL, ZERO); 204 205 CreateCommandMenu(box, "xt"); 206 CreateTreeCommandMenu(box, "xt"); 207 208 hPane = XtCreateManagedWidget("hPane",panedWidgetClass, parent, NULL,ZERO); 209 210 { 211 panner = XtCreateManagedWidget("panner", pannerWidgetClass, 212 hPane, NULL, ZERO); 213 214 global_screen_data.info_label = XtCreateManagedWidget("xt", 215 labelWidgetClass, 216 hPane, NULL,ZERO); 217 218 /* get the "xt label" application resources for info_label */ 219 XtGetApplicationResources(global_screen_data.info_label, 220 res_labels, resources, 221 XtNumber(resources), NULL, 0); 222 223 } 224 225 return(panner); 226} 227 228 229 230/* Function Name: SetEntriesInsensitive 231 * Description: Make menu entries unusable. 232 * Arguments: entries - address of widget array. 233 * num - number of widgets. 234 * sensitive - whether to sensitize or desensitize. 235 * Returns: none. 236 */ 237void 238SetEntriesSensitive(Widget *entries, int num, Boolean sensitive) 239{ 240int i; for (i=0; i<num; i++) XtSetSensitive(entries[i], sensitive); 241} 242 243 244 245/* Function Name: CreateCommandMenu 246 * Description: Creates the command menu. 247 * Arguments: parent - widget to put this menu into. 248 * toolkit - name given to the SimpleMenu widget. 249 * Returns: none. 250 */ 251 252static Widget cmenu = NULL, cbutton = NULL; 253/* at first most menu entries are insensitive */ 254static Boolean CM_set_insensitive = True; 255Widget CM_entries[NUM_CM_ENTRIES]; 256 257static void 258CreateCommandMenu(Widget parent, String toolkit) 259{ 260 Arg args[1]; 261 262 if (cmenu) { XtDestroyWidget(cmenu); CM_set_insensitive = False; } 263 else 264 cbutton = XtCreateManagedWidget("commands", menuButtonWidgetClass, 265 parent, NULL, ZERO); 266 267 /* set the menu name to the toolkit name */ 268 XtSetArg(args[0], XtNmenuName, toolkit); 269 XtSetValues(cbutton, args, ONE); 270 271 cmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, cbutton, 272 NULL, ZERO); 273 274 CM_entries[0] = XtCreateManagedWidget("sendTree", smeBSBObjectClass,cmenu, 275 NULL, ZERO); 276 XtAddCallback(CM_entries[0], XtNcallback, SendTree, (XtPointer) TRUE); 277 278 CM_entries[1]=XtCreateManagedWidget("refreshTree",smeBSBObjectClass,cmenu, 279 NULL, ZERO); 280 XtAddCallback(CM_entries[1], XtNcallback, SendTree, (XtPointer) FALSE); 281 282 CM_entries[2] = XtCreateManagedWidget("dumpTreeToFile", 283 smeBSBObjectClass,cmenu, 284 NULL, ZERO); 285 XtAddCallback(CM_entries[2], XtNcallback, DumpTreeToFile, NULL); 286 287 CM_entries[3] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu, 288 NULL, ZERO); 289 CM_entries[4]= XtCreateManagedWidget("getResourceList", 290 smeBSBObjectClass,cmenu, 291 NULL, ZERO); 292 XtAddCallback(CM_entries[4], XtNcallback, GetResourceList, NULL); 293 294 CM_entries[5] = XtCreateManagedWidget("setValues", smeBSBObjectClass, 295 cmenu, 296 NULL, ZERO); 297 XtAddCallback(CM_entries[5], XtNcallback, InitSetValues, NULL); 298 299 CM_entries[6] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu, 300 NULL, ZERO); 301 302 CM_entries[7] = XtCreateManagedWidget("quit", smeBSBObjectClass, cmenu, 303 NULL, ZERO); 304 XtAddCallback(CM_entries[7], XtNcallback, Quit, NULL); 305 306 if (CM_set_insensitive) 307 SetEntriesSensitive(&CM_entries[CM_OFFSET], CM_NUM, False); 308} 309 310 311 312/* Function Name: CreateTreeCommandMenu 313 * Description: Creates the command menu. 314 * Arguments: parent - widget to put this menu into. 315 * Returns: none. 316 */ 317 318#define SELECT 0 319#define ACTIVATE 1 320#define LABEL 2 321#define LINE 3 322#define FIND 4 323#define FLASH 5 324 325struct tree_ops_menu { 326 const char * name; 327 int type; 328 XtPointer data; 329}; 330 331static Widget tmenu = NULL, tbutton = NULL; 332/* at first most menu entries are insensitive */ 333static Boolean TM_set_insensitive = True; 334Widget TM_entries[NUM_TM_ENTRIES]; 335 336static void 337CreateTreeCommandMenu(Widget parent, String toolkit) 338{ 339 int i, number; 340 static struct tree_ops_menu tree_menu[] = { 341 { "showClientWidget", FIND, (XtPointer) NULL }, 342 { "selectAll", SELECT, (XtPointer) SelectAll }, 343 { "unselectAll", SELECT, (XtPointer) SelectNone }, 344 { "invertAll", SELECT, (XtPointer) SelectInvert }, 345 { "line", LINE, (XtPointer) NULL }, 346 { "selectChildren", SELECT, (XtPointer) SelectChildren }, 347 { "selectParent", SELECT, (XtPointer) SelectParent }, 348 { "selectDescendants", SELECT, (XtPointer) SelectDescendants }, 349 { "selectAncestors", SELECT, (XtPointer) SelectAncestors }, 350 { "line", LINE, (XtPointer) NULL }, 351 { "showWidgetNames", LABEL, (XtPointer) NameLabel }, 352 { "showClassNames", LABEL, (XtPointer) ClassLabel }, 353 { "showWidgetIDs", LABEL, (XtPointer) IDLabel}, 354 { "showWidgetWindows", LABEL, (XtPointer) WindowLabel }, 355 { "line", LINE, (XtPointer) NULL }, 356 { "flashActiveWidgets", FLASH, (XtPointer) NULL } 357 }; 358 Arg args[1]; 359 360 if (tmenu) { XtDestroyWidget(tmenu); TM_set_insensitive = False; } 361 else 362 tbutton = XtCreateManagedWidget("treeCommands", menuButtonWidgetClass, 363 parent, NULL, ZERO); 364 365 XtSetArg(args[0], XtNmenuName, toolkit); 366 XtSetValues(tbutton, args, ONE); 367 368 tmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, tbutton, 369 NULL, ZERO); 370 371 for ( i = 0, number = XtNumber(tree_menu) ; i < number ; i++) { 372 XtCallbackProc func; 373 WidgetClass class = smeBSBObjectClass; 374 375 switch (tree_menu[i].type) { 376 case SELECT: 377 func = TreeSelect; 378 break; 379 case LABEL: 380 func = TreeRelabel; 381 break; 382 case LINE: 383 func = NULL; 384 class = smeLineObjectClass; 385 break; 386 case FIND: 387 func = FindWidget; 388 break; 389 case FLASH: 390 func = FlashActiveWidgets; 391 break; 392 default: 393 continue; 394 } 395 396 TM_entries[i] = XtCreateManagedWidget(tree_menu[i].name, class, tmenu, 397 NULL, ZERO); 398 if (func != NULL) 399 XtAddCallback(TM_entries[i], XtNcallback, func,tree_menu[i].data); 400 } 401 if (TM_set_insensitive) SetEntriesSensitive(&TM_entries[TM_OFFSET], 402 TM_NUM, False); 403} 404 405 406 407static Pixmap old_pixmap; 408 409/* Function Name: PrepareToLayoutTree 410 * Description: prepares the Tree widget to be laid out. 411 * Arguments: tree - the Tree widget. 412 * Returns: none 413 */ 414 415void 416PrepareToLayoutTree(Widget tree) 417{ 418 Arg args[1]; 419 420 XtSetArg(args[0], XtNbackgroundPixmap, &old_pixmap); 421 XtGetValues(XtParent(tree), args, ONE); 422 423 XtSetArg(args[0], XtNbackgroundPixmap, None); 424 XtSetValues(XtParent(tree), args, ONE); 425 426 XtUnmapWidget(tree); 427} 428 429 430 431/* Function Name: LayoutTree 432 * Description: Laysout the tree widget. 433 * Arguments: tree - the widget tree. 434 * Returns: none. 435 */ 436 437void 438LayoutTree(Widget tree) 439{ 440 Arg args[1]; 441 442 XawTreeForceLayout(tree); 443 XtMapWidget(tree); 444 445 XtSetArg(args[0], XtNbackgroundPixmap, old_pixmap); 446 XtSetValues(XtParent(tree), args, ONE); 447} 448 449 450 451/************************************************************ 452 * 453 * Functions for creating the Resource Box. 454 * 455 ************************************************************/ 456 457/* Function Name: CreateResourceBoxWidgets 458 * Description: Creates the widgets that make up the resource box. 459 * Arguments: node - the widget node. 460 * names - the list of names that make up the normal resources. 461 * cons_names - the list of names that make up 462 * the constraint resources. 463 * Returns: none. 464 */ 465 466void 467CreateResourceBoxWidgets(WNode *node, char **names, char **cons_names) 468{ 469 Widget pane, box, button, viewport, pane_child; 470 ResourceBoxInfo * res_box; 471 Dimension max_width = WidthOfScreen(XtScreen(node->widget)) - 20; 472 Dimension max_height = HeightOfScreen(XtScreen(node->widget)) - 40; 473 474 res_box = (ResourceBoxInfo *) XtMalloc(sizeof(ResourceBoxInfo)); 475 node->resources->res_box = res_box; 476 477 res_box->shell = XtVaCreatePopupShell(global_effective_toolkit, 478 /*RESOURCE_BOX,*/ 479 transientShellWidgetClass, 480 node->widget, 481 XtNmaxWidth, max_width, 482 XtNmaxHeight, max_height, NULL); 483 XtAddCallback(res_box->shell, XtNdestroyCallback, 484 FreeResBox, (XtPointer) node); 485 486 pane = XtCreateManagedWidget("pane", panedWidgetClass, 487 res_box->shell, NULL, ZERO); 488 489 viewport = XtCreateManagedWidget("mainViewport", viewportWidgetClass, 490 pane, NULL, 0); 491 pane_child = XtCreateManagedWidget("pane", panedWidgetClass, 492 viewport, NULL, ZERO); 493 494 res_box->res_label = XtCreateManagedWidget("resourceLabel", 495 labelWidgetClass, 496 pane_child, NULL, ZERO); 497 498 CreateResourceNameForm(pane_child, node); 499 CreateLists(pane_child, node, names, cons_names); 500 CreateValueWidget(pane, node); 501 502 XtSetKeyboardFocus(pane, res_box->value_wid); /* send keyboard to value. */ 503 504 box = XtCreateManagedWidget("commandBox", boxWidgetClass, 505 pane, NULL, ZERO); 506 507 button = XtCreateManagedWidget("setFile", commandWidgetClass, 508 box, NULL, ZERO); 509 XtAddCallback(button, XtNcallback, SetFile, NULL); 510 511 button = XtCreateManagedWidget("save", commandWidgetClass, 512 box, NULL, ZERO); 513 XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box); 514 515 button = XtCreateManagedWidget("apply", commandWidgetClass, 516 box, NULL, ZERO); 517 XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node); 518 519 button = XtCreateManagedWidget("saveAndApply", commandWidgetClass, 520 box, NULL, ZERO); 521 XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box); 522 XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node); 523 524 button = XtCreateManagedWidget("cancel", commandWidgetClass, 525 box, NULL, ZERO); 526 XtAddCallback(button,XtNcallback,PopdownResBox,(XtPointer)res_box->shell); 527 528 SetToggleGroupLeaders(node); 529 PopupOnNode(node, res_box->shell); 530} 531 532 533 534/* Function Name: CreateResourceNameForm 535 * Description: Creates the Form widget with children that represent 536 * the full resource name for this object. 537 * Arguments: parent - parent of the form. 538 * node - the node corrosponding to this object. 539 * Returns: none 540 */ 541 542static void 543CreateResourceNameForm(Widget parent, WNode *node) 544{ 545 ResourceBoxInfo * res_box = node->resources->res_box; 546 AnyInfo *new_info = NULL, *old_info; 547 char **names, **classes; 548 Widget form; 549 NameInfo * name_info = NULL; 550 Cardinal num_args; 551 Arg args[10]; 552 int i; 553 Widget dot, star, name, class, single, any; 554 555 GetNamesAndClasses(node, &names, &classes); 556 557 form = XtCreateManagedWidget("namesAndClasses", formWidgetClass, 558 parent, NULL, ZERO); 559 560 name = class = any = NULL; 561 i = 0; 562 old_info = NULL; 563 while (TRUE) { 564 565 num_args = 0; 566 XtSetArg(args[num_args], XtNfromHoriz, name); num_args++; 567 XtSetArg(args[num_args], XtNradioData, "."); num_args++; 568 dot = XtCreateManagedWidget("dot", toggleWidgetClass, 569 form, args, num_args); 570 XtAddCallback(dot, XtNcallback, 571 ActivateWidgetsAndSetResourceString,(XtPointer) node); 572 573 num_args = 0; 574 XtSetArg(args[num_args], XtNfromHoriz, class); num_args++; 575 XtSetArg(args[num_args], XtNfromVert, dot); num_args++; 576 XtSetArg(args[num_args], XtNradioGroup, dot); num_args++; 577 XtSetArg(args[num_args], XtNradioData, "*"); num_args++; 578 star = XtCreateManagedWidget("star", toggleWidgetClass, 579 form, args, num_args); 580 XtAddCallback(star,XtNcallback, 581 ActivateWidgetsAndSetResourceString, (XtPointer) node); 582 583 if (name_info != NULL) { 584 name_info->next = (NameInfo *) XtMalloc(sizeof(NameInfo)); 585 name_info = name_info->next; 586 } 587 else 588 res_box->name_info = 589 name_info = (NameInfo *) XtMalloc(sizeof(NameInfo)); 590 591 name_info->sep_leader = dot; 592 name_info->name_leader = NULL; 593 594 if (names[i] != NULL) { 595 new_info = (AnyInfo *) XtMalloc(sizeof(AnyInfo)); 596 new_info->node = node; 597 new_info->left_dot = dot; 598 new_info->left_star = star; 599 new_info->left_count = 0; 600 if (old_info != NULL) 601 old_info->right_count = &(new_info->left_count); 602 } 603 else if (old_info != NULL) 604 old_info->right_count = NULL; 605 606 if (old_info != NULL) { 607 old_info->right_dot = dot; 608 old_info->right_star = star; 609 610 XtAddCallback(any, XtNcallback, AnyChosen, (XtPointer) old_info); 611 XtAddCallback(any, XtNdestroyCallback, 612 FreeClientData, (XtPointer) old_info); 613 } 614 615 if ( names[i] == NULL) /* no more name and class boxes. */ 616 break; 617 618 old_info = new_info; 619 620 num_args = 0; 621 XtSetArg(args[num_args], XtNfromHoriz, dot); num_args++; 622 XtSetArg(args[num_args], XtNlabel, names[i]); num_args++; 623 XtSetArg(args[num_args], XtNradioData, names[i]); num_args++; 624 name = XtCreateManagedWidget("name", toggleWidgetClass, 625 form, args, num_args); 626 XtAddCallback(name,XtNcallback, 627 ActivateWidgetsAndSetResourceString,(XtPointer) node); 628 629 num_args = 0; 630 XtSetArg(args[num_args], XtNfromHoriz, star); num_args++; 631 XtSetArg(args[num_args], XtNfromVert, name); num_args++; 632 XtSetArg(args[num_args], XtNlabel, classes[i]); num_args++; 633 XtSetArg(args[num_args], XtNradioGroup, name); num_args++; 634 XtSetArg(args[num_args], XtNradioData, classes[i]); num_args++; 635 class = XtCreateManagedWidget("class", toggleWidgetClass, 636 form,args,num_args); 637 XtAddCallback(class, XtNcallback, 638 ActivateWidgetsAndSetResourceString,(XtPointer) node); 639 640 num_args = 0; 641 XtSetArg(args[num_args], XtNfromHoriz, star); num_args++; 642 XtSetArg(args[num_args], XtNfromVert, class); num_args++; 643 XtSetArg(args[num_args], XtNradioData, "?"); num_args++; 644 XtSetArg(args[num_args], XtNradioGroup, name); num_args++; 645 single = XtCreateManagedWidget("single", toggleWidgetClass, 646 form, args, num_args); 647 XtAddCallback(single,XtNcallback, 648 ActivateWidgetsAndSetResourceString,(XtPointer) node); 649 650 num_args = 0; 651 XtSetArg(args[num_args], XtNfromHoriz, any); num_args++; 652 XtSetArg(args[num_args], XtNfromVert, single); num_args++; 653 XtSetArg(args[num_args], XtNradioGroup, name); num_args++; 654 XtSetArg(args[num_args], XtNradioData, ANY_RADIO_DATA); num_args++; 655 any = XtCreateManagedWidget("any", toggleWidgetClass, 656 form, args, num_args); 657 658 name_info->name_leader = name; 659 660 MakeBoxLookNice(dot, star, any, single, name, class, 661 (i == 0 ? -1 : (names[i + 1] ? 0 : 1))); 662 663 i++; 664 } 665 666 name_info->next = NULL; 667 XtFree((char *)names); /* Free what you allocate... */ 668 XtFree((char *)classes); 669} 670 671 672 673/* Function Name: SetToggleGroupLeaders 674 * Description: Sets the leaders of each toggle group. 675 * node - The widget node containing this res box. 676 * Returns: none 677 */ 678 679static void 680SetToggleGroupLeaders(WNode *node) 681{ 682 NameInfo *name; 683 ResourceBoxInfo * res_box = node->resources->res_box; 684 static Arg args[] = { 685 {XtNstate, (XtArgVal) TRUE} 686 }; 687 688 for (name = res_box->name_info; name != NULL; name = name->next) { 689 XtSetValues(name->sep_leader, args, XtNumber(args)); 690 if (name->name_leader != NULL) 691 XtSetValues(name->name_leader, args, XtNumber(args)); 692 } 693 SetResourceString(NULL, (XtPointer) node, NULL); 694} 695 696 697 698/* Function Name: MakeBoxLookNice 699 * Description: Resizes the box that contains the resource names 700 * to look a bit nicer. 701 * Arguments: dot, star - the widgets containing the separator types. 702 * any, single, name, class - the widgets that contain the 703 * name and class of this object. 704 * Returns: none. 705 */ 706 707static void 708MakeBoxLookNice(Widget dot, Widget star, Widget any, Widget single, 709 Widget name, Widget class, int endbox) 710{ 711 712#define MAX_HDIST 3 713 714 Arg args[10]; 715 Cardinal num_args; 716 Dimension any_width, name_class_width, dot_star_width; 717 Dimension width_1, width_2; 718 int h_dist[MAX_HDIST]; 719 int i; 720 721 /* 722 * Make sure that the dot and star widgets are the same size. 723 */ 724 725 num_args = 0; 726 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++; 727 XtSetArg(args[num_args], XtNwidth, &width_1); num_args++; 728 XtGetValues(dot, args, num_args); 729 730 num_args = 0; 731 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++; 732 XtSetArg(args[num_args], XtNwidth, &width_2); num_args++; 733 XtGetValues(star, args, num_args); 734 735 num_args = 0; 736 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[2])); num_args++; 737 XtSetArg(args[num_args], XtNwidth, &any_width); num_args++; 738 XtGetValues(any, args, num_args); 739 740 dot_star_width = (width_1 > width_2) ? width_1 : width_2; 741 for (i = 1 ; i < MAX_HDIST; i++) { 742 if (h_dist[i] > h_dist[0]) h_dist[0] = h_dist[i]; 743 } 744 745 num_args = 0; 746 XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++; 747 XtSetValues(any, args, num_args); 748 749 /* 750 * Add a new arg, and continue... 751 */ 752 XtSetArg(args[num_args], XtNwidth, dot_star_width); num_args++; 753 XtSetValues(star, args, num_args); 754 XtSetValues(dot, args, num_args); 755 756 757 /* 758 * Now make sure that the Any Widget is as wide as the longest 759 * of the name and class widgets, plus space for the dot and star widgets. 760 * Don't forget the Form widget's internal space. 761 */ 762 763 num_args = 0; 764 XtSetArg(args[num_args], XtNwidth, &width_1); num_args++; 765 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++; 766 XtGetValues(name, args, num_args); 767 768 num_args = 0; 769 XtSetArg(args[num_args], XtNwidth, &width_2); num_args++; 770 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++; 771 XtGetValues(class, args, num_args); 772 773 if (width_2 > width_1) width_1 = width_2; 774 if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1]; 775 776 num_args = 0; 777 XtSetArg(args[num_args], XtNwidth, &width_2); num_args++; 778 XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++; 779 XtGetValues(single, args, num_args); 780 781 name_class_width = (width_1 > width_2) ? width_1 : width_2; 782 if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1]; 783 if (any_width > name_class_width) 784 name_class_width = any_width; 785 any_width = dot_star_width + h_dist[0] + name_class_width; 786 787 num_args = 0; 788 if (endbox < 0) { 789 any_width -= dot_star_width & 1; 790 XtSetArg(args[num_args], XtNhorizDistance, 791 h_dist[2] + (dot_star_width >> 1) + (dot_star_width & 1)); 792 ++num_args; 793 } 794 795 XtSetArg(args[num_args], XtNwidth, any_width); num_args++; 796 XtSetValues(any, args, num_args); 797 798 num_args = 0; 799 XtSetArg(args[num_args], XtNwidth, name_class_width); num_args++; 800 XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++; 801 XtSetValues(name, args, num_args); 802 XtSetValues(class, args, num_args); 803 XtSetValues(single, args, num_args); 804} 805 806 807 808/* Function Name: CreateLists 809 * Description: Creates the list widgets for the normal and constraint 810 * resources 811 * Arguments: parent - parent of the lists. 812 * node - The widget node containing this res box. 813 * names, cons_names - lists for norm and cons resource boxes. 814 * Returns: none 815 */ 816 817static const char *noneList[] = {"None"}; 818 819static void 820CreateLists(Widget parent, WNode *node, char **names, char **cons_names) 821{ 822 Widget viewport; 823 Cardinal num_args; 824 ResourceBoxInfo * res_box = node->resources->res_box; 825 Arg args[3]; 826 827 (void) XtCreateManagedWidget("namesLabel", labelWidgetClass, 828 parent, NULL, ZERO); 829 830 num_args = 0; 831 /* if the first list item is the widget name we want an empty 832 * list. 833 */ 834 if (!names) { 835 XtSetArg(args[num_args], XtNlist, noneList); num_args++; 836 XtSetArg(args[num_args], XtNnumberStrings, 1); num_args++; 837 XtSetArg(args[num_args], XtNsensitive, False); num_args++; 838 } 839 else { XtSetArg(args[num_args], XtNlist, names); num_args++; } 840 viewport = XtCreateManagedWidget("normalViewport", viewportWidgetClass, 841 parent, NULL, 0); 842 res_box->norm_list = XtCreateManagedWidget("namesList", listWidgetClass, 843 viewport, args, num_args); 844 XtAddCallback(res_box->norm_list, XtNcallback, 845 ResourceListCallback, (XtPointer) node); 846 XtAddCallback(res_box->norm_list, XtNdestroyCallback, 847 FreeClientData, (XtPointer) names); 848 849 if (cons_names != NULL) { 850 (void) XtCreateManagedWidget("constraintLabel", labelWidgetClass, 851 parent, NULL, ZERO); 852 853 num_args = 0; 854 XtSetArg(args[num_args], XtNlist, cons_names); num_args++; 855 viewport = XtCreateManagedWidget("constraintViewport", viewportWidgetClass, 856 parent, NULL, 0); 857 res_box->cons_list = XtCreateManagedWidget("constraintList", 858 listWidgetClass, 859 viewport, args, num_args); 860 XtAddCallback(res_box->cons_list, XtNcallback, 861 ResourceListCallback, (XtPointer) node); 862 XtAddCallback(res_box->cons_list, XtNdestroyCallback, 863 FreeClientData, (XtPointer) cons_names); 864 } 865 else 866 res_box->cons_list = NULL; 867} 868 869/* Function Name: CreateValueWidget 870 * Description: Creates the value widget for entering the resources value. 871 * Arguments: parent - parent of this widget. 872 * res_box - the resource box info. 873 * Returns: none. 874 */ 875 876static void 877CreateValueWidget(Widget parent, WNode *node) 878{ 879 Widget form, label; 880 Cardinal num_args; 881 Arg args[10]; 882 ResourceBoxInfo * res_box = node->resources->res_box; 883 884 form = XtCreateManagedWidget("valueForm", formWidgetClass, 885 parent, NULL, ZERO); 886 887 num_args = 0; 888 XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++; 889 XtSetArg(args[num_args], XtNright, XawChainLeft); num_args++; 890 XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++; 891 XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++; 892 label = XtCreateManagedWidget("valueLabel", labelWidgetClass, 893 form, args, num_args); 894 895 num_args = 0; 896 XtSetArg(args[num_args], XtNfromHoriz, label); num_args++; 897 XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++; 898 XtSetArg(args[num_args], XtNright, XawChainRight); num_args++; 899 XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++; 900 XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++; 901 res_box->value_wid = XtCreateManagedWidget("valueText", 902 asciiTextWidgetClass, 903 form, args, num_args); 904#ifdef notdef 905 XtAddCallback(XawTextGetSource(res_box->value_wid), XtNcallback, 906 SetResourceString, (XtPointer) node); 907#endif 908} 909 910 911 912/* Function Name: PopupOnNode 913 * Description: Pops a shell widget up centered on the node specified. 914 * Arguments: node - the node. 915 * shell - the shell to popup. 916 * Returns: none. 917 */ 918 919static void 920PopupOnNode(WNode *node, Widget shell) 921{ 922 Arg args[3]; 923 Cardinal num_args; 924 Position x, y, max_loc; 925 Dimension width, height, bw; 926 927 num_args = 0; 928 XtSetArg(args[num_args], XtNwidth, &width); num_args++; 929 XtSetArg(args[num_args], XtNheight, &height); num_args++; 930 XtSetArg(args[num_args], XtNborderWidth, &bw); num_args++; 931 XtGetValues(node->widget, args, num_args); 932 XtTranslateCoords(node->widget, 933 (Position) (width/2 + bw), (Position) (height/2 + bw), 934 &x, &y); 935 936 XtOverrideTranslations 937 (shell, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()")); 938 XtRealizeWidget(shell); 939 wm_delete_window = XInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW", 940 False); 941 (void) XSetWMProtocols (XtDisplay(shell), XtWindow(shell), 942 &wm_delete_window, 1); 943 XtGetValues(shell, args, num_args); /* use same arg_list. */ 944 945 x -= (Position) (width/2 + bw); 946 y -= (Position) (height/2 + bw); 947 948 max_loc = WidthOfScreen(XtScreen(shell)) - (Position) (width + 2 * bw); 949 if (x > max_loc) 950 x = max_loc; 951 if (x < 0) 952 x = 0; 953 954 max_loc = HeightOfScreen(XtScreen(shell)) - (Position) (height + 2 * bw); 955 if (y > max_loc) 956 y = max_loc; 957 if (y < 0) 958 y = 0; 959 960 num_args = 0; 961 XtSetArg(args[num_args], XtNx, x); num_args++; 962 XtSetArg(args[num_args], XtNy, y); num_args++; 963 XtSetValues(shell, args, num_args); 964 965 XtPopup(shell, XtGrabNone); 966} 967 968 969 970/* Function Name: FreeClientData 971 * Description: Frees the client data passed to this function. 972 * Arguments: w - UNUSED. 973 * list_ptr - pointer to the list to check. 974 * junk - UNUSED. 975 * Returns: none 976 */ 977 978/* ARGSUSED */ 979static void 980FreeClientData(Widget w, XtPointer ptr, XtPointer junk) 981{ 982 XtFree(ptr); 983} 984 985 986 987/* Function Name: FreeResBox. 988 * Description: Frees resource box allocated memory. 989 * Arguments: w - UNUSED. 990 * ptr - pointer to the node that has this resources box. 991 * junk - UNUSED. 992 * Returns: none 993 */ 994 995/* ARGSUSED */ 996static void 997FreeResBox(Widget w, XtPointer ptr, XtPointer junk) 998{ 999 WNode * node = (WNode *) ptr; 1000 NameInfo *old_name, *name = node->resources->res_box->name_info; 1001 1002 global_resource_box_up = FALSE; 1003 1004 XtFree((XtPointer) node->resources->res_box); 1005 node->resources->res_box = NULL; 1006 1007 while (name != NULL) { 1008 old_name = name; 1009 name = name->next; 1010 XtFree((XtPointer) old_name); 1011 } 1012} 1013 1014 1015 1016