utils.c revision 33c89af1
1/* 2 * $Xorg: utils.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $ 3 * 4Copyright 1989, 1998 The Open Group 5 6Permission to use, copy, modify, distribute, and sell this software and its 7documentation for any purpose is hereby granted without fee, provided that 8the above copyright notice appear in all copies and that both that 9copyright notice and this permission notice appear in supporting 10documentation. 11 12The above copyright notice and this permission notice shall be included in 13all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall not be 23used in advertising or otherwise to promote the sale, use or other dealings 24in this Software without prior written authorization from The Open Group. 25 */ 26/* $XFree86: xc/programs/editres/utils.c,v 1.5 2001/04/01 14:00:17 tsi Exp $ */ 27 28#include <X11/Intrinsic.h> 29#include <X11/Xutil.h> 30#include <X11/Xos.h> 31#include <X11/Shell.h> 32#include <X11/StringDefs.h> 33 34#include <X11/Xaw/Cardinals.h> 35#include <X11/Xaw/Dialog.h> 36 37#include <stdio.h> 38#include <stdlib.h> 39#include <X11/Xmu/Error.h> 40 41#include "editresP.h" 42 43static WNode * FindWidgetFromWindowGivenNode ( WNode * node, Window win ); 44static WidgetResources * ParseResources ( GetResourcesInfo * info, 45 char **error ); 46static int CompareResourceEntries ( const void *e1, 47 const void *e2 ); 48static void AddResource ( ResourceInfo * res_info, 49 WidgetResourceInfo * resource ); 50static void FreeResources ( WidgetResources * resources ); 51 52 53/* Function Name: SetMessage(w, str) 54 * Description: shows the message to the user. 55 * Arguments: w - a label widget to show the message in. 56 * str - the string to show. 57 * Returns: none. 58 */ 59 60void 61SetMessage(w, str) 62Widget w; 63char * str; 64{ 65 Arg args[1]; 66 67 XtSetArg(args[0], XtNlabel, str); 68 XtSetValues(w, args, ONE); 69} 70 71/* Function Name: GetAllStrings 72 * Description: Returns a list of strings that have been borken up by 73 * the character specified. 74 * Arguments: in - the string to parse. 75 * sep - the separator character. 76 * out - the strings to send out. 77 * num - the number of strings in out. 78 * Returns: none 79 */ 80 81void 82GetAllStrings(char *in, char sep, char ***out, int *num) 83{ 84 int size, i; 85 char * ptr; 86 87 if (*in == sep) /* jump over first char if it is the sep. */ 88 in++; 89 90 /* 91 * count the number of strings. 92 */ 93 94 for (*num = 1, ptr = in; (ptr = strchr(ptr, sep)) != NULL; (*num)++) 95 ptr++; 96 97/* 98 * Create Enough space for pointers and string. 99 */ 100 101 size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1)); 102 *out = (char **) XtMalloc( (Cardinal) size); 103 104 ptr = (char *) (*out + *num); 105 strcpy(ptr, in); 106 107/* 108 * Change all `sep' characters to '\0' and stuff the pointer into 109 * the next pointer slot. 110 */ 111 112 i = 1; 113 (*out)[0] = ptr; 114 while (TRUE) { 115 if ((ptr = strchr(ptr, sep)) == NULL) 116 break; 117 118 *ptr++ = '\0'; 119 (*out)[i++] = ptr; 120 } 121 122/* 123 * If last string is empty then strip it off. 124 */ 125 126 if ( *((*out)[i - 1]) == '\0' ) 127 (*num)--; 128} 129 130/* Function Name: AddString 131 * Description: Mallocs and strcats the string onto the end of 132 * the given string. 133 * Arguments: str - string to add on to. 134 * add - string to add. 135 * Returns: none. 136 */ 137 138void 139AddString(str, add) 140char ** str, *add; 141{ 142 int len_str, len_add; 143 char * ptr; 144 145 len_str = ((*str) ? strlen(*str) : 0); 146 len_add = strlen(add); 147 148 *str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1)); 149 ptr = *str + len_str; 150 strcpy(ptr, add); 151} 152 153/* Function Name: FindNode 154 * Description: Finds a node give the top node, and a node id number. 155 * Arguments: top_node - the top node. 156 * id - the node id. 157 * Returns: node. 158 */ 159 160WNode * 161FindNode(top_node, ids, number) 162WNode *top_node; 163unsigned long * ids; 164Cardinal number; 165{ 166 int i, j; 167 WNode *node; 168 169 if (top_node == NULL) 170 return(NULL); 171 172 if (ids[0] != top_node->id) 173 return(NULL); 174 175 for (node = top_node, i = 1 ; i < number; i++) { 176 Boolean found_it = FALSE; 177 178 for (j = 0; j < node->num_children; j++) { 179 if (node->children[j]->id == ids[i]) { 180 node = node->children[j]; 181 found_it = TRUE; 182 break; 183 } 184 } 185 if (!found_it) 186 return(NULL); 187 } 188 return(node); 189} 190 191/* Function Name: FindWidgetFromWindow 192 * Description: finds a widget in the current tree given its window id. 193 * Arguments: tree_info - information about this tree. 194 * win - window to search for. 195 * Returns: node - the node corrosponding to this widget. 196 */ 197 198WNode * 199FindWidgetFromWindow(tree_info, win) 200TreeInfo * tree_info; 201Window win; 202{ 203 if (tree_info == NULL) 204 return(NULL); 205 206 return(FindWidgetFromWindowGivenNode(tree_info->top_node, win)); 207} 208 209/* Function Name: FindWidgetFromWindowGivenNode 210 * Description: finds a widget in the current tree given its window id. 211 * Arguments: node - current node. 212 * win - window to search for. 213 * Returns: node - the node corrosponding to this widget. 214 */ 215 216static WNode * 217FindWidgetFromWindowGivenNode(node, win) 218WNode * node; 219Window win; 220{ 221 int i; 222 WNode * ret_node; 223 224 if (node->window == win) 225 return(node); 226 227 for (i = 0; i < node->num_children; i++) { 228 ret_node = FindWidgetFromWindowGivenNode(node->children[i], win); 229 if (ret_node != NULL) 230 return(ret_node); 231 } 232 return(NULL); 233} 234 235/* Function Name: HandleXErrors 236 * Description: Handles error codes from the server. 237 * Arguments: display - the display. 238 * error - error information. 239 * Returns: none. 240 */ 241 242/* ARGSUSED */ 243int 244HandleXErrors(display, error) 245Display * display; 246XErrorEvent * error; 247{ 248 if (error->serial != global_serial_num) { 249 (*global_old_error_handler) (display, error); 250 return(0); 251 } 252 253 if (error->error_code == BadWindow) 254 global_error_code = NO_WINDOW; 255 else { 256 if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0) 257 exit(1); 258 } 259 return(0); 260} 261 262/* Function Name: _DumpTreeToFile 263 * Description: Dumps the widget tree to a file 264 * Arguments: w - a random widget in the application on the 265 * currently active display 266 * tree_ptr - pointer to the widget tree info. 267 * filename - name of the file. 268 * Returns: none. 269 */ 270 271/* ARGSUSED */ 272 273void 274_DumpTreeToFile(w, tree_ptr, filename) 275Widget w; 276XtPointer tree_ptr; 277XtPointer filename; 278{ 279 TreeInfo * tree_info = (TreeInfo *) tree_ptr; 280 FILE * fp; 281 282 if (tree_info == NULL) { 283 SetMessage(global_screen_data.info_label, 284 res_labels[17]); 285 return; 286 } 287 288 if ( (fp = fopen((char *)filename, "w")) == NULL ) { 289 char buf[BUFSIZ]; 290 291 sprintf(buf, res_labels[24], (char *)filename); 292 SetMessage(global_screen_data.info_label, buf); 293 return; 294 } 295 296 PerformTreeToFileDump(tree_info->top_node, 0, fp); 297 fclose(fp); 298} 299 300/************************************************************ 301 * 302 * The file dialog boxes are handled with this code. 303 * 304 * It automatically calls the function specified when the 305 * user selects okay, or hits <CR>. 306 * 307 * A translation is required in the app-defaults file. 308 * 309 ************************************************************/ 310 311/* Function Name: _PopupFileDialog 312 * Description: Puts up a dialog box to get the filename. 313 * Arguments: str - message. 314 * default_value - the default value of the filename; 315 * func - function to call when filename has been entered. 316 * data - generic data to pass to func. 317 * Returns: none 318 */ 319 320static XContext file_dialog_context = None; 321 322typedef struct _FileDialogInfo { 323 XtCallbackProc func; 324 XtPointer data; 325} FileDialogInfo; 326 327void 328_PopupFileDialog(w, str, default_value, func, data) 329Widget w; 330String str, default_value; 331XtCallbackProc func; 332XtPointer data; 333{ 334 FileDialogInfo * file_info; 335 Widget shell, dialog; 336 Arg args[2]; 337 Cardinal num_args; 338 339 if (file_dialog_context == None) 340 file_dialog_context = XUniqueContext(); 341 342 shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w, 343 NULL, ZERO); 344 345 num_args = 0; 346 XtSetArg(args[num_args], XtNlabel, str); num_args++; 347 XtSetArg(args[num_args], XtNvalue, default_value); num_args++; 348 dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, 349 shell, args, num_args); 350 351 file_info = XtNew(FileDialogInfo); 352 353 file_info->func = func; 354 file_info->data = data; 355 356 if (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context, 357 (XPointer) file_info) != 0) { 358 SetMessage(global_screen_data.info_label, 359 "Error while trying to save Context\nAborting file dialog popup."); 360 XtDestroyWidget(shell); 361 return; 362 } 363 364 XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE); 365 XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE); 366 367 PopupCentered(NULL, shell, XtGrabNone); 368} 369 370/* Function Name: PopupCentered 371 * Description: Pops up the window specified under the location passed 372 * in the event, or under the cursor. 373 * Arguments: event - the event that we should use. 374 * w - widget to popup. 375 * mode - mode to pop it up in. 376 * Returns: none 377 */ 378 379void 380PopupCentered(event, w, mode) 381XEvent * event; 382Widget w; 383XtGrabKind mode; 384{ 385 Boolean get_from_cursor = FALSE; 386 Arg args[3]; 387 Cardinal num_args; 388 Dimension width, height, b_width; 389 int x, y, max_x, max_y; 390 391 XtRealizeWidget(w); 392 393 if (event == NULL) 394 get_from_cursor = TRUE; 395 else { 396 switch (event->type) { 397 case ButtonPress: 398 case ButtonRelease: 399 x = event->xbutton.x_root; 400 y = event->xbutton.y_root; 401 break; 402 case KeyPress: 403 case KeyRelease: 404 x = event->xkey.x_root; 405 y = event->xkey.y_root; 406 break; 407 default: 408 get_from_cursor = TRUE; 409 break; 410 } 411 } 412 413 if (get_from_cursor) { 414 Window root, child; 415 int win_x, win_y; 416 unsigned int mask; 417 418 XQueryPointer(XtDisplay(w), XtWindow(w), 419 &root, &child, &x, &y, &win_x, &win_y, &mask); 420 } 421 422 num_args = 0; 423 XtSetArg(args[num_args], XtNwidth, &width); num_args++; 424 XtSetArg(args[num_args], XtNheight, &height); num_args++; 425 XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++; 426 XtGetValues(w, args, num_args); 427 428 width += 2 * b_width; 429 height += 2 * b_width; 430 431 x -= ((int) width/2); 432 if (x < 0) 433 x = 0; 434 if ( x > (max_x = (int) (XtScreen(w)->width - width)) ) 435 x = max_x; 436 437 y -= ( (Position) height/2 ); 438 if (y < 0) 439 y = 0; 440 if ( y > (max_y = (int) (XtScreen(w)->height - height)) ) 441 y = max_y; 442 443 num_args = 0; 444 XtSetArg(args[num_args], XtNx, x); num_args++; 445 XtSetArg(args[num_args], XtNy, y); num_args++; 446 XtSetValues(w, args, num_args); 447 448 XtPopup(w, mode); 449} 450 451/* Function Name: _PopdownFileDialog 452 * Description: Destroys the file dialog, and calls the correct function. 453 * Arguments: w - a child of the dialog widget. 454 * client_data - TRUE if command was sucessful. 455 * junk - ** UNUSED **. 456 * Returns: none. 457 */ 458 459/* ARGSUSED */ 460 461void 462_PopdownFileDialog(w, client_data, junk) 463Widget w; 464XtPointer client_data, junk; 465{ 466 Widget dialog = XtParent(w); 467 XPointer file_info_ptr; 468 FileDialogInfo * file_info; 469 470 if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context, 471 &file_info_ptr) == XCNOENT) { 472 SetMessage(global_screen_data.info_label, 473 "Error while trying to find Context\nAborting..."); 474 } 475 476 (void) XDeleteContext(XtDisplay(dialog), (Window)dialog, 477 file_dialog_context); 478 479 file_info = (FileDialogInfo *) file_info_ptr; 480 481 if ( ((Boolean)(long) client_data) == TRUE ) { 482 String filename = XawDialogGetValueString(dialog); 483 484 (*file_info->func)(w, file_info->data, filename); /* call handler */ 485 } 486 487 XtFree( (XtPointer) file_info); /* Free data. */ 488 489 XtPopdown(XtParent(dialog)); 490 XtDestroyWidget(XtParent(dialog)); /* Remove file dialog. */ 491} 492 493/************************************************************ 494 * 495 * Functions for dealing with the Resource Box. 496 * 497 ************************************************************/ 498 499/* Function Name: GetNamesAndClasses 500 * Description: Gets a list of names and classes for this widget. 501 * Arguments: node - this widget's node. 502 * names, classes - list of names and classes. ** RETURNED ** 503 * Returns: none. 504 */ 505 506void 507GetNamesAndClasses(node, names, classes) 508WNode * node; 509char *** names, ***classes; 510{ 511 int i, total_widgets; 512 WNode * temp = node; 513 514 for (total_widgets = 1 ; temp->parent != NULL ; 515 total_widgets++, temp = temp->parent) {} 516 517 *names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1)); 518 *classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1)); 519 520 (*names)[total_widgets] = (*classes)[total_widgets] = NULL; 521 522 for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) { 523 (*names)[i] = node->name; 524 (*classes)[i] = node->class; 525 } 526} 527 528/* Function Name: HandleGetResources 529 * Description: Gets the resources. 530 * Arguments: event - the information from the client. 531 * Returns: an error message to display. 532 */ 533 534char * 535HandleGetResources(event) 536Event * event; 537{ 538 GetResourcesEvent * get_event = (GetResourcesEvent *) event; 539 char buf[BUFSIZ], * errors = NULL; 540 int i; 541 WNode * node; 542 543 for (i = 0; i < (int)get_event->num_entries; i++) { 544 node = FindNode(global_tree_info->top_node, 545 get_event->info[i].widgets.ids, 546 get_event->info[i].widgets.num_widgets); 547 548 if (node == NULL) { 549 sprintf(buf, res_labels[16]); 550 AddString(&errors, buf); 551 continue; 552 } 553 554 if (node->resources != NULL) 555 FreeResources(node->resources); 556 557 if (!get_event->info[i].error) { 558 node->resources = ParseResources(get_event->info + i, &errors); 559 CreateResourceBox(node, &errors); 560 } 561 else { 562 AddString(&errors, get_event->info[i].message); 563 AddString(&errors, "\n"); 564 } 565 } 566 567 return(errors); 568} 569 570/* Function Name: CreateResourceBox 571 * Description: Creates a resource box for the widget specified. 572 * Arguments: node - the node of the widget in question. 573 * errors - an error string. 574 * Returns: none. 575 */ 576 577void 578CreateResourceBox(node, errors) 579WNode * node; 580char ** errors; 581{ 582 WidgetResources * resources = node->resources; 583 char ** names, ** cons_names; 584 int i; 585 586 if (global_resource_box_up) { 587 AddString(errors, res_labels[34]); 588 return; 589 } 590 else 591 global_resource_box_up = TRUE; 592 593 if (resources->num_normal > 0) { 594 names = (char **) XtMalloc(sizeof(char *) * 595 (resources->num_normal + 1)); 596 for (i = 0 ; i < resources->num_normal ; i++) 597 names[i] = resources->normal[i].name; 598 names[i] = NULL; 599 } 600 else 601 names = NULL; 602 603 if (resources->num_constraint > 0) { 604 cons_names = (char **) XtMalloc(sizeof(char *) * 605 (resources->num_constraint + 1)); 606 607 for (i = 0 ; i < resources->num_constraint ; i++) 608 cons_names[i] = resources->constraint[i].name; 609 cons_names[i] = NULL; 610 } 611 else 612 cons_names = NULL; 613 614 CreateResourceBoxWidgets(node, names, cons_names); 615} 616 617/* Function Name: ParseResources 618 * Description: Parses the resource values returned from the client 619 * into a resources structure. 620 * Arguments: info - info about a widget's resources. 621 * error - where to place error info. 622 * Returns: The resource information. 623 */ 624 625static WidgetResources * 626ParseResources(info, error) 627GetResourcesInfo * info; 628char **error; 629{ 630 WidgetResources * resources; 631 WidgetResourceInfo * normal; 632 int i; 633 634 resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources)); 635 636 /* 637 * Allocate enough space for both the normal and constraint resources, 638 * then add the normal resources from the top, and the constraint resources 639 * from the bottom. This assures that enough memory is allocated, and 640 * that there is no overlap. 641 */ 642 643 resources->normal = (WidgetResourceInfo *) 644 XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources); 645 646 normal = resources->normal; 647 resources->constraint = resources->normal + info->num_resources - 1; 648 649 resources->num_constraint = resources->num_normal = 0; 650 651 for (i = 0; i < (int)info->num_resources; i++) { 652 switch((int) info->res_info[i].res_type) { 653 case NormalResource: 654 resources->num_normal++; 655 AddResource(info->res_info + i, normal++); 656 break; 657 case ConstraintResource: 658 resources->num_constraint++; 659 AddResource(info->res_info + i, resources->constraint--); 660 break; 661 default: 662 { 663 char buf[BUFSIZ]; 664 sprintf(buf, "Unknown resource type %d\n", 665 info->res_info[i].res_type); 666 AddString(error, buf); 667 } 668 break; 669 } 670 } 671 672 /* 673 * Sort the resources alphabetically. 674 */ 675 676 qsort(resources->normal, resources->num_normal, 677 sizeof(WidgetResourceInfo), CompareResourceEntries); 678 679 if (resources->num_constraint > 0) { 680 resources->constraint++; 681 qsort(resources->constraint, resources->num_constraint, 682 sizeof(WidgetResourceInfo), CompareResourceEntries); 683 } 684 else 685 resources->constraint = NULL; 686 687 return(resources); 688} 689 690/* Function Name: CompareResourceEntries 691 * Description: Compares two resource entries. 692 * Arguments: e1, e2 - the entries to compare. 693 * Returns: an integer >, < or = 0. 694 */ 695 696static int 697CompareResourceEntries(e1, e2) 698const void *e1, *e2; 699{ 700 return (strcmp(((WidgetResourceInfo *)e1)->name, 701 ((WidgetResourceInfo *)e2)->name)); 702} 703 704/* Function Name: AddResource 705 * Description: Parses the resource string a stuffs in individual 706 * parts into the resource info struct. 707 * Arguments: res_info - the resource info from the event. 708 * resource - location to stuff the resource into. 709 * Returns: none. 710 */ 711 712static void 713AddResource(res_info, resource) 714ResourceInfo * res_info; 715WidgetResourceInfo * resource; 716{ 717 resource->name = res_info->name; 718 res_info->name = NULL; /* Keeps it from being deallocated. */ 719 resource->class = res_info->class; 720 res_info->class = NULL; /* Keeps it from being deallocated. */ 721 resource->type = res_info->type; 722 res_info->type = NULL; /* Keeps it from being deallocated. */ 723} 724 725 726/* Function Name: FreeResources 727 * Description: frees the resource inforation. 728 * Arguments: resources. 729 * Returns: none. 730 */ 731 732static void 733FreeResources(resources) 734WidgetResources * resources; 735{ 736 int i; 737 738 if (resources->num_normal > 0) { 739 for (i = 0; i < resources->num_normal; i++) { 740 XtFree(resources->normal[i].name); 741 XtFree(resources->normal[i].class); 742 XtFree(resources->normal[i].type); 743 } 744 XFree((char *)resources->normal); 745 } 746 747 if (resources->num_constraint > 0) { 748 for (i = 0; i < resources->num_constraint; i++) { 749 XtFree(resources->constraint[i].name); 750 XtFree(resources->constraint[i].class); 751 XtFree(resources->constraint[i].type); 752 } 753 XFree((char *)resources->constraint); 754 } 755 756 XFree((char *)resources); 757} 758 759 760/* Function Name: CheckDatabase 761 * Description: Checks to see if the node is in the database. 762 * Arguments: db - the db to check 763 * names, clases - names and clases, represented as quarks. 764 * Returns: True if this entry is found. 765 */ 766 767Boolean 768CheckDatabase(db, names, classes) 769XrmDatabase db; 770XrmQuarkList names, classes; 771{ 772 XrmRepresentation junk; 773 XrmValue garbage; 774 775 return(XrmQGetResource(db, names, classes, &junk, &garbage)); 776} 777 778/* Function Name: Quarkify 779 * Description: Quarkifies the string list specifed. 780 * Arguments: list - list of strings to quarkify 781 * ptr - an additional string to quarkify. 782 * Returns: none. 783 */ 784 785XrmQuarkList 786Quarkify(list, ptr) 787char ** list; 788char * ptr; 789{ 790 int i; 791 char ** tlist; 792 XrmQuarkList quarks, tquarks; 793 794 for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {} 795 if (ptr != NULL) 796 i++; 797 i++; /* leave space for NULLQUARK */ 798 799 quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i); 800 801 for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++) 802 *tquarks = XrmStringToQuark(*tlist); 803 804 if (ptr != NULL) 805 *tquarks++ = XrmStringToQuark(ptr); 806 807 *tquarks = NULLQUARK; 808 return(quarks); 809} 810 811/* Function Name: ExecuteOverAllNodes 812 * Description: Executes the given function over all nodes. 813 * Arguments: top_node - top node of the tree. 814 * func - the function to execute. 815 * data - a data pointer to pass to the function. 816 * Returns: none 817 */ 818 819void 820ExecuteOverAllNodes(top_node, func, data) 821WNode * top_node; 822void (*func)(WNode *, XtPointer); 823XtPointer data; 824{ 825 int i; 826 827 (*func)(top_node, data); 828 829 for (i = 0; i < top_node->num_children; i++) 830 ExecuteOverAllNodes(top_node->children[i], func, data); 831} 832 833/* Function Name: InsertWidgetFromNode 834 * Description: Inserts the widget info for this widget represented 835 * by this node. 836 * Arguments: stream - the stream to insert it info into. 837 * none - the widget node to insert. 838 * Returns: none 839 */ 840 841void 842InsertWidgetFromNode(stream, node) 843ProtocolStream * stream; 844WNode * node; 845{ 846 WNode *temp; 847 unsigned long * widget_list; 848 register int i, num_widgets; 849 850 for (temp = node, i = 0; temp != 0; temp = temp->parent, i++) {} 851 852 num_widgets = i; 853 widget_list = (unsigned long *) 854 XtMalloc(sizeof(unsigned long) * num_widgets); 855 856 /* 857 * Put the widgets into the list. 858 * Make sure that they are inserted in the list from parent -> child. 859 */ 860 861 for (i--, temp = node; temp != 0; temp = temp->parent, i--) 862 widget_list[i] = temp->id; 863 864 _XEditResPut16(stream, num_widgets); /* insert number of widgets. */ 865 for (i = 0; i < num_widgets; i++) /* insert Widgets themselves. */ 866 _XEditResPut32(stream, widget_list[i]); 867 868 XtFree((char *)widget_list); 869} 870 871/* Function Name: GetFailureMesssage 872 * Description: returns the message returned from a failed request. 873 * Arguments: stream - the protocol stream containing the message. 874 * Returns: message to show. 875 */ 876 877char * 878GetFailureMessage(stream) 879ProtocolStream * stream; 880{ 881 char * return_str; 882 883 if (_XEditResGetString8(stream, &return_str)) 884 return(return_str); 885 886 return(XtNewString(res_labels[35])); 887} 888 889/* Function Name: ProtocolFailure 890 * Description: Gets the version of the protocol the client is 891 * willing to speak. 892 * Arguments: stream - the protocol stream containing the message. 893 * Returns: message to show. 894 */ 895 896char * 897ProtocolFailure(stream) 898ProtocolStream * stream; 899{ 900 char buf[BUFSIZ]; 901 unsigned char version; 902 char* old_version_string; 903 904 if (!_XEditResGet8(stream, &version)) 905 return(XtNewString(res_labels[35])); 906 907 switch ((int)version) { 908 case PROTOCOL_VERSION_ONE_POINT_ZERO: old_version_string = "1.0"; break; 909 default: old_version_string = "1.0"; 910 } 911 912 sprintf(buf, res_labels[36], 913 CURRENT_PROTOCOL_VERSION_STRING, old_version_string); 914 return(XtNewString(buf)); 915} 916 917