home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / editres / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  22.7 KB  |  908 lines

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