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

  1. /*
  2.  * $XConsortium: handler.c,v 1.26 92/02/11 11:45:31 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/StringDefs.h>
  26.  
  27. #include <X11/Xaw/Cardinals.h>
  28. #include <X11/Xaw/List.h>
  29. #include <X11/Xaw/Panner.h>
  30. #include <X11/Xaw/Toggle.h>
  31. #include <X11/Xfuncs.h>
  32. #include <X11/Xos.h>        /* for W_OK def */
  33.  
  34. #include <stdio.h>
  35.  
  36. #include "editresP.h"
  37.  
  38. /* 
  39.  * Function Definitions.
  40.  */
  41.  
  42. extern void SetCommand(), PopupSetValues(), SetAndCenterTreeNode();
  43. extern void _TreeSelect(), _TreeRelabel(), _TreeActivate(), SetMessage();
  44. extern void _FlashActiveWidgets(), _DumpTreeToFile(), _PopupFileDialog();
  45. extern void AddString(), CreateResourceBox(), ExecuteOverAllNodes();
  46. extern void GetNamesAndClasses(), TreeToggle(), InsertWidgetFromNode();
  47. extern Boolean CheckDatabase();
  48. extern XrmQuarkList Quarkify();
  49. extern char *GetResourceValueForSetValues();
  50.  
  51. void SetResourceString(), ActivateResourceWidgets();
  52. void ActivateWidgetsAndSetResourceString();
  53. static void SetOnlyMatchingWidgets();
  54. static void CreateSetValuesCommand();
  55.  
  56. extern Widget toplevel;
  57.  
  58. /*    Function Name: Quit
  59.  *    Description: This function prints a message to stdout.
  60.  *    Arguments: w - ** UNUSED **
  61.  *                 call_data - ** UNUSED **
  62.  *                 client_data - ** UNUSED **
  63.  *    Returns: none
  64.  */
  65.  
  66. /* ARGSUSED */
  67. void
  68. Quit(w, client_data, call_data)
  69. Widget w;
  70. XtPointer call_data, client_data;
  71. {
  72.     XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
  73.     exit(0);
  74. }
  75.  
  76. /*    Function Name: SendTree
  77.  *    Description: This function initiates the client communication.
  78.  *    Arguments: w - the widget that made the selection.
  79.  *                 value - a boolean value stored as a pointer.
  80.  *                         if True then get a new client, otherwise
  81.  *                         refresh the current client.
  82.  *                 call_data - ** UNUSED **
  83.  *    Returns: none
  84.  */
  85.  
  86. /* ARGSUSED */
  87. void
  88. SendTree(w, value, call_data)
  89. Widget w;
  90. XtPointer value, call_data;
  91. {
  92.     if ((Boolean) value)
  93.     global_client.window = None;
  94.  
  95.     if (!XtIsWidget(w))     /* Make sure that we use a "Real" widget here. */
  96.     w = XtParent(w);
  97.  
  98.     _XEditResResetStream(&(global_client.stream)); /* an empty message. */
  99.     SetCommand(w, LocalSendWidgetTree, NULL);
  100. }
  101.  
  102. /*    Function Name: FindWidget
  103.  *    Description: Maps a widget in the client to one in the currently
  104.  *                   displayed widget tree.
  105.  *    Arguments: w - the widget that invoked this action.
  106.  *                 call_data, client_data ** UNUSED **
  107.  *    Returns: none
  108.  */
  109.  
  110. /* ARGSUSED */
  111. void
  112. FindWidget(w, client_data, call_data)
  113. Widget w;
  114. XtPointer client_data, call_data;
  115. {
  116.     void _FindWidget();
  117.  
  118.     _FindWidget(XtParent(w));    /* Use parent since it is a "real"
  119.                    widget not a rect_obj. */
  120. }
  121.  
  122. /*    Function Name: InitSetValues
  123.  *    Description: This function pops up the setvalues dialog
  124.  *    Arguments: w - the widget caused this action.
  125.  *                 call_data - ** UNUSED **
  126.  *                 client_data - ** UNUSED **
  127.  *    Returns: none
  128.  */
  129.  
  130. /* ARGSUSED */
  131. void
  132. InitSetValues(w, client_data, call_data)
  133. Widget w;
  134. XtPointer call_data, client_data;
  135. {
  136.     if (!XtIsWidget(w))     /* Make sure that we use a "Real" widget here. */
  137.     w = XtParent(w);
  138.  
  139.     PopupSetValues(w, NULL);
  140. }
  141.  
  142. /*    Function Name: TreeSelect
  143.  *    Description: Selects all widgets.
  144.  *    Arguments: w - the widget caused this action.
  145.  *                 call_data - ** UNUSED **
  146.  *                 client_data - The type of thing to select.
  147.  *    Returns: none
  148.  */
  149.  
  150. /* ARGSUSED */
  151. void
  152. TreeSelect(w, client_data, call_data)
  153. Widget w;
  154. XtPointer call_data, client_data;
  155. {
  156.     SelectTypes type = (SelectTypes) client_data;
  157.  
  158.     _TreeSelect(global_tree_info, type);
  159. }
  160.  
  161. /*    Function Name: TreeRelabel
  162.  *    Description: Relabels a tree to the type specified.
  163.  *    Arguments: w - the widget caused this action.
  164.  *                 call_data - ** UNUSED **
  165.  *                 client_data - the type of label to assign to each node.
  166.  *    Returns: none
  167.  */
  168.  
  169. /* ARGSUSED */
  170. void
  171. TreeRelabel(w, client_data, call_data)
  172. Widget w;
  173. XtPointer call_data, client_data;
  174. {
  175.     LabelTypes type = (LabelTypes) client_data;
  176.  
  177.     _TreeRelabel(global_tree_info, type);
  178. }
  179.  
  180. /*    Function Name: PannerCallback
  181.  *    Description: called when the panner has moved.
  182.  *    Arguments: panner - the panner widget.
  183.  *                 closure - *** NOT USED ***.
  184.  *                 report_ptr - the panner record.
  185.  *    Returns: none.
  186.  */
  187.  
  188. /* ARGSUSED */
  189. void 
  190. PannerCallback(w, closure, report_ptr)
  191. Widget w;
  192. XtPointer closure, report_ptr;
  193. {
  194.     Arg args[2];
  195.     XawPannerReport *report = (XawPannerReport *) report_ptr;
  196.  
  197.     if (global_tree_info == NULL) 
  198.     return;
  199.  
  200.     XtSetArg (args[0], XtNx, -report->slider_x);
  201.     XtSetArg (args[1], XtNy, -report->slider_y);
  202.  
  203.     XtSetValues(global_tree_info->tree_widget, args, TWO);
  204. }
  205.  
  206. /*    Function Name: PortholeCallback
  207.  *    Description: called when the porthole or its child has
  208.  *                   changed 
  209.  *    Arguments: porthole - the porthole widget.
  210.  *                 panner_ptr - the panner widget.
  211.  *                 report_ptr - the porthole record.
  212.  *    Returns: none.
  213.  */
  214.  
  215. /* ARGSUSED */
  216. void 
  217. PortholeCallback(w, panner_ptr, report_ptr)
  218. Widget w;
  219. XtPointer panner_ptr, report_ptr;
  220. {
  221.     Arg args[10];
  222.     Cardinal n = 0;
  223.     XawPannerReport *report = (XawPannerReport *) report_ptr;
  224.     Widget panner = (Widget) panner_ptr;
  225.  
  226.     XtSetArg (args[n], XtNsliderX, report->slider_x); n++;
  227.     XtSetArg (args[n], XtNsliderY, report->slider_y); n++;
  228.     if (report->changed != (XawPRSliderX | XawPRSliderY)) {
  229.     XtSetArg (args[n], XtNsliderWidth, report->slider_width); n++;
  230.     XtSetArg (args[n], XtNsliderHeight, report->slider_height); n++;
  231.     XtSetArg (args[n], XtNcanvasWidth, report->canvas_width); n++;
  232.     XtSetArg (args[n], XtNcanvasHeight, report->canvas_height); n++;
  233.     }
  234.     XtSetValues (panner, args, n);
  235. }
  236.  
  237. /*    Function Name: FlashActiveWidgets
  238.  *    Description: called to flass all active widgets in the display.
  239.  *    Arguments: *** NOT USED ***
  240.  *    Returns: none.
  241.  */
  242.  
  243. /* ARGSUSED */
  244. void 
  245. FlashActiveWidgets(w, junk, garbage)
  246. Widget w;
  247. XtPointer junk, garbage;
  248. {
  249.     _FlashActiveWidgets(global_tree_info);
  250. }
  251.  
  252. /*    Function Name: GetResourceList
  253.  *    Description: Gets the resources lists of all active widgets.
  254.  *    Arguments: ** NOT USED **
  255.  *    Returns: none
  256.  */
  257.  
  258. /* ARGSUSED */
  259. void
  260. GetResourceList(w, junk, garbage)
  261. Widget w;
  262. XtPointer junk, garbage;
  263. {
  264.     WNode * node;
  265.     ProtocolStream * stream = &(global_client.stream);
  266.  
  267.     if (global_tree_info == NULL) {
  268.     SetMessage(global_screen_data.info_label,
  269.            "No widget Tree is avaliable.");
  270.     return;
  271.     }
  272.  
  273.     if (global_tree_info->num_nodes != 1) {
  274.     SetMessage(global_screen_data.info_label,
  275.           "This function requires exactly one (1) widget to be selected.");
  276.     return;
  277.     }
  278.  
  279.     node = global_tree_info->active_nodes[0];
  280.     if (node->resources != NULL) {
  281.     char * errors = NULL;
  282.     CreateResourceBox(node, &errors);
  283.     if (errors != NULL) {
  284.         SetMessage(global_screen_data.info_label, errors);
  285.         XtFree(errors);
  286.     }
  287.     return;
  288.     }
  289.  
  290.     /*
  291.      * No resoruces, fetch them from the client.
  292.      */
  293.  
  294.     _XEditResResetStream(stream); 
  295.     _XEditResPut16(stream, (unsigned short) 1);
  296.     InsertWidgetFromNode(stream, node);
  297.     SetCommand(global_tree_info->tree_widget, LocalGetResources, NULL);
  298. }
  299.  
  300. /*    Function Name: DumpTreeToFile
  301.  *    Description: Dumps all widgets in the tree to a file.
  302.  *    Arguments: w - the widget that activated this callback.
  303.  *                 junk, garbage - ** NOT USED **.
  304.  *    Returns: none.
  305.  */
  306.  
  307. /* ARGSUSED */
  308. void 
  309. DumpTreeToFile(w, junk, garbage)
  310. Widget w;
  311. XtPointer junk, garbage;
  312. {
  313.     _PopupFileDialog(XtParent(w), "Enter the filename:", "",
  314.              _DumpTreeToFile, (XtPointer) global_tree_info);
  315. }
  316.  
  317. /************************************************************
  318.  * 
  319.  * Callbacks for the Resource Box.
  320.  *
  321.  ************************************************************/
  322.  
  323.  
  324. /*    Function Name: AnyChosen
  325.  *    Description: Callback that is called when the "any" widget 
  326.  *                   is activated.
  327.  *    Arguments: w - the "any" widget that activated this callback.
  328.  *                 any_info_ptr - pointer to struct containing 
  329.  *                                dot and star widgets to lock.
  330.  *                 state_ptr - state of the any toggle.
  331.  *    Returns: none.
  332.  */
  333.  
  334. /* ARGSUSED */
  335. void 
  336. AnyChosen(w, any_info_ptr, state_ptr)
  337. Widget w;
  338. XtPointer any_info_ptr, state_ptr;
  339. {
  340.     AnyInfo * any_info = (AnyInfo *) any_info_ptr;
  341.     Boolean state = (Boolean) state_ptr;
  342.     Arg args[1];
  343.  
  344.     if (state) {
  345.  
  346.     if (any_info->left_count == 0) {
  347.         XtSetSensitive(any_info->left_dot, FALSE);
  348.         XtSetSensitive(any_info->left_star, FALSE);
  349.  
  350.         XtSetArg(args[0], XtNstate, TRUE);
  351.         XtSetValues(any_info->left_star, args, ONE);
  352.     }
  353.  
  354.     if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
  355.         XtSetSensitive(any_info->right_dot, FALSE);
  356.         XtSetSensitive(any_info->right_star, FALSE);
  357.  
  358.         XtSetArg(args[0], XtNstate, TRUE);
  359.         XtSetValues(any_info->right_star, args, ONE);
  360.     }
  361.     any_info->left_count++;
  362.  
  363.     if (any_info->right_count != NULL)
  364.         (*any_info->right_count)++;
  365.     }
  366.     else {            /* state == 0 */
  367.     if (any_info->left_count > 0) 
  368.         any_info->left_count--;
  369.     if ((any_info->right_count != NULL)&&(*any_info->right_count > 0)) 
  370.         (*any_info->right_count)--;
  371.  
  372.     if (any_info->left_count == 0) {
  373.         XtSetSensitive(any_info->left_dot, TRUE);
  374.         XtSetSensitive(any_info->left_star, TRUE);
  375.  
  376.         XtSetArg(args[0], XtNstate, TRUE);
  377.         XtSetValues(any_info->left_dot, args, ONE);
  378.     }
  379.  
  380.     if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
  381.         XtSetSensitive(any_info->right_dot, TRUE);
  382.         XtSetSensitive(any_info->right_star, TRUE);
  383.  
  384.         XtSetArg(args[0], XtNstate, TRUE);
  385.         XtSetValues(any_info->right_dot, args, ONE);
  386.     }
  387.     }
  388.     SetResourceString(NULL, (XtPointer) any_info->node, NULL);
  389.     ActivateResourceWidgets(NULL, (XtPointer) any_info->node, NULL);
  390. }
  391.  
  392. /*    Function Name: GetResourceName
  393.  *    Description: Gets the name of the current resource.
  394.  *    Arguments: res_box - the resource box.
  395.  *    Returns: the name of the currently selected resource.
  396.  */
  397.  
  398.  
  399. static char *
  400. GetResourceName(res_box)
  401. ResourceBoxInfo * res_box;
  402. {
  403.     XawListReturnStruct * list_info;
  404.     char * result;
  405.     
  406.     list_info = XawListShowCurrent(res_box->norm_list);
  407.     if ((list_info->list_index == XAW_LIST_NONE) && 
  408.     (res_box->cons_list != NULL)) {
  409.     list_info = XawListShowCurrent(res_box->cons_list);
  410.     }
  411.  
  412.     if (list_info->list_index == XAW_LIST_NONE) 
  413.     result = "unknown";
  414.     else
  415.     result = list_info->string;    
  416.  
  417.     return(result);
  418. }
  419.  
  420.  
  421. /*    Function Name: ActivateWidgetsAndSetResourceString
  422.  *    Description: Sets the new resources string, then
  423.  *                   activates all widgets that match this resource,
  424.  *    Arguments: w - the widget that activated this.
  425.  *                 node_ptr - the node that owns this resource box.
  426.  *                 call_data - passed on to other callbacks.
  427.  *    Returns: none.
  428.  *
  429.  * NOTE: I cannot just have two callback routines, since I care which
  430.  *       order that these are executed in, sigh...
  431.  */
  432.  
  433. void
  434. ActivateWidgetsAndSetResourceString(w, node_ptr, call_data)
  435. Widget w;
  436. XtPointer node_ptr, call_data;
  437. {
  438.     SetResourceString(w, node_ptr, call_data);
  439.     ActivateResourceWidgets(w, node_ptr, call_data);
  440. }
  441.  
  442. /*    Function Name: SetResourceString
  443.  *    Description: Sets the resource label to correspond to the currently
  444.  *                   chosen string.
  445.  *    Arguments: w - The widget that invoked this callback, or NULL.
  446.  *                 node_ptr - pointer to widget node contating this res box.
  447.  *                 call_data - The call data for the action that invoked
  448.  *                             this callback.
  449.  *    Returns: none.
  450.  */
  451.  
  452. void
  453. SetResourceString(w, node_ptr, junk)
  454. Widget w;
  455. XtPointer node_ptr, junk;
  456. {
  457.     static char * malloc_string; /* These are both inited to zero. */
  458.     static Cardinal malloc_size;
  459.  
  460.     WNode * node = (WNode *) node_ptr;
  461.     ResourceBoxInfo * res_box = node->resources->res_box;
  462.     char * temp, buf[BUFSIZ * 10];    /* here's hoping it's big enough. */
  463.     NameInfo * name_node = res_box->name_info;
  464.     Arg args[1];
  465.     int len;
  466.  
  467.     if ((w != NULL) && XtIsSubclass(w, toggleWidgetClass)) {
  468.     /*
  469.      * Only set resources when toggles are activated, not when they are
  470.      * deactivated. 
  471.      */
  472.     if (!((Boolean) junk))
  473.         return;
  474.     }
  475.  
  476.     buf[0] = '\0';        /* clear out string. */
  477.  
  478.     /*
  479.      * Get the widget name/class info.
  480.      */
  481.  
  482.     if ((temp = (char *) XawToggleGetCurrent(name_node->sep_leader)) != NULL)
  483.     strcat(buf, temp);
  484.  
  485.     for ( ; name_node->next != NULL ; name_node = name_node->next) {
  486.     temp = (char *) XawToggleGetCurrent(name_node->name_leader);
  487.     if ( (temp != NULL) && !streq(temp, ANY_RADIO_DATA) ) {
  488.         strcat(buf, temp);
  489.         temp = (char *) XawToggleGetCurrent(name_node->next->sep_leader);
  490.         if (temp == NULL) 
  491.         strcat(buf, "!");
  492.         else
  493.         strcat(buf, temp);
  494.     }
  495.     }
  496.         
  497.     strcat(buf, GetResourceName(res_box));
  498.     len = strlen(buf) + 2; /* Leave space for ':' and '\0' */
  499.  
  500. #ifdef notdef
  501.     XtSetArg(args[0], XtNstring, &temp);
  502.     XtGetValues(res_box->value_wid, args, ONE);
  503.     len += strlen(temp);
  504. #endif
  505.  
  506.     if (len > malloc_size) {
  507.     malloc_string = XtRealloc(malloc_string, sizeof(char) * len);
  508.     malloc_size = len;
  509.     }
  510.     
  511.     strcpy(malloc_string, buf);
  512.     strcat(malloc_string, ":");
  513. #ifdef notdef
  514.     strcat(malloc_string, temp);
  515. #endif
  516.  
  517.     XtSetArg(args[0], XtNlabel, malloc_string);
  518.     XtSetValues(res_box->res_label, args, ONE);
  519. }
  520.     
  521. /*    Function Name: ResourceListCallback
  522.  *    Description: Callback functions for the resource lists.
  523.  *    Arguments: list - the list widget that we are dealing with.
  524.  *                 node_ptr - pointer to widget node contating this res box.
  525.  *                 junk - UNUSED.
  526.  *    Returns: none
  527.  */
  528.  
  529. void
  530. ResourceListCallback(list, node_ptr, junk)
  531. Widget list;
  532. XtPointer node_ptr, junk;
  533. {
  534.     Widget o_list;
  535.     WNode * node = (WNode *) node_ptr;
  536.     ResourceBoxInfo * res_box = node->resources->res_box;
  537.  
  538.     if (list == res_box->norm_list) 
  539.     o_list = res_box->cons_list;
  540.     else
  541.     o_list = res_box->norm_list;
  542.  
  543.     if (o_list != NULL)
  544.     XawListUnhighlight(o_list);
  545.  
  546.     SetResourceString(list, node_ptr, junk);
  547. }
  548.  
  549. /*    Function Name: PopdownResBox
  550.  *    Description: Pops down the resource box.
  551.  *    Arguments: w - UNUSED
  552.  *                 shell_ptr - pointer to the shell to pop down.
  553.  *                 junk - UNUSED.
  554.  *    Returns: none
  555.  */
  556.  
  557. /* ARGSUSED */
  558. void
  559. PopdownResBox(w, shell_ptr, junk)
  560. Widget w;
  561. XtPointer shell_ptr, junk;
  562. {
  563.     Widget shell = (Widget) shell_ptr;
  564.  
  565.     XtPopdown(shell);
  566.     XtDestroyWidget(shell);
  567. }
  568.  
  569. /*    Function Name: _AppendResourceString
  570.  *    Description: Actually append the resource string to your resoruce file.
  571.  *    Arguments: w - UNUSED
  572.  *                 res_box_ptr - the resource box info.
  573.  *                 filename_ptr - a pointer to the filename;
  574.  *    Returns: none
  575.  */
  576.  
  577. /* ARGSUSED */
  578. static void
  579. _AppendResourceString(w, res_box_ptr, filename_ptr)
  580. Widget w;
  581. XtPointer res_box_ptr, filename_ptr;
  582. {
  583.     Arg args[1];
  584.     FILE * fp;
  585.     char buf[BUFSIZ], * resource_string, *filename = (char *) filename_ptr;
  586.     ResourceBoxInfo * res_box = (ResourceBoxInfo *) res_box_ptr;
  587.     char *value_ptr;
  588.  
  589.     if (filename != NULL) {
  590.     if (global_resources.allocated_save_resources_file) 
  591.         XtFree(global_resources.save_resources_file);
  592.     else
  593.         global_resources.allocated_save_resources_file = TRUE;
  594.     
  595.     global_resources.save_resources_file = XtNewString(filename);
  596.     }
  597.  
  598.     if ((fp = fopen(global_resources.save_resources_file, "a+")) == NULL) {
  599.     sprintf(buf, "Unable to open this file for writing, would %s",
  600.         "you like To try again?");
  601.     _PopupFileDialog(toplevel ,buf,
  602.             global_resources.save_resources_file,
  603.             _AppendResourceString, res_box_ptr);
  604.     return;
  605.     }
  606.  
  607.     XtSetArg(args[0], XtNlabel, &resource_string);
  608.     XtGetValues(res_box->res_label, args, ONE);
  609.  
  610.     XtSetArg(args[0], XtNstring, &value_ptr);
  611.     XtGetValues(res_box->value_wid, args, ONE);
  612.  
  613.     fprintf(fp, "%s %s\n", resource_string, value_ptr);
  614.  
  615.     fclose(fp);
  616. }
  617.  
  618. /*    Function Name: SaveResource
  619.  *    Description: Save the current resource to your resource file
  620.  *    Arguments: w - any widget in the application.
  621.  *                 res_box_ptr - the resource box info.
  622.  *                 junk - UNUSED.
  623.  *    Returns: none
  624.  */
  625.  
  626. /* ARGSUSED */
  627. void
  628. SaveResource(w, res_box_ptr, junk)
  629. Widget w;
  630. XtPointer res_box_ptr, junk;
  631. {
  632.     /* 
  633.      * If there is no filename the ask for one, otherwise just save to
  634.      * current file.
  635.      */
  636.  
  637.     if (streq(global_resources.save_resources_file, ""))
  638.     _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
  639.              global_resources.save_resources_file,
  640.              _AppendResourceString, res_box_ptr);
  641.     else
  642.     _AppendResourceString(w, res_box_ptr, NULL);
  643. }
  644.  
  645. /*    Function Name: _SetResourcesFile
  646.  *    Description: Sets the filename of the file to save the resources to.
  647.  *    Arguments: w - UNUSED
  648.  *                 junk - UNUSED
  649.  *                 filename_ptr - a pointer to the filename;
  650.  *    Returns: none
  651.  */
  652.  
  653. /* ARGSUSED */
  654. static void
  655. _SetResourcesFile(w, junk, filename_ptr)
  656. Widget w;
  657. XtPointer junk, filename_ptr;
  658. {
  659.     char buf[BUFSIZ], *filename = (char *) filename_ptr;
  660.  
  661.     if (global_resources.allocated_save_resources_file) 
  662.     XtFree(global_resources.save_resources_file);
  663.     else
  664.     global_resources.allocated_save_resources_file = TRUE;
  665.  
  666.     global_resources.save_resources_file = XtNewString(filename);
  667. }
  668.  
  669. /*    Function Name: SetFile
  670.  *    Description: Changes the current save file
  671.  *    Arguments: w - UNUSED.
  672.  *                 res_box_ptr - UNUSED.
  673.  *                 junk - UNUSED.
  674.  *    Returns: none
  675.  */
  676.  
  677. /* ARGSUSED */
  678. void
  679. SetFile(w, junk, garbage)
  680. Widget w;
  681. XtPointer junk, garbage;
  682. {
  683.     /* 
  684.      * If there is no filename the ask for one, otherwise just save to
  685.      * current file.
  686.      */
  687.  
  688.     _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
  689.              global_resources.save_resources_file,
  690.              _SetResourcesFile, NULL);
  691. }
  692.  
  693. /*    Function Name: ApplyResource
  694.  *    Description: Apply the current resource to the running application.
  695.  *    Arguments: w - any widget in the application.
  696.  *                 node_ptr - a pointer to the node containing 
  697.  *                            the current resouce box.
  698.  *                 junk - UNUSED.
  699.  *    Returns: none
  700.  */
  701.  
  702. /* ARGSUSED */
  703. void
  704. ApplyResource(w, node_ptr, junk)
  705. Widget w;
  706. XtPointer node_ptr, junk;
  707. {
  708.     ProtocolStream * stream = &(global_client.stream);
  709.     ApplyResourcesInfo info;
  710.     WNode * node = (WNode *) node_ptr;           
  711.     char * value;
  712.     unsigned short size, i;
  713.     long len;
  714.     Arg args[1];
  715.  
  716.     info.name = GetResourceName(node->resources->res_box);
  717.     info.class = "IGNORE_ME";    /* Not currently used.  */
  718.     info.stream = stream;
  719.     info.count = 0;
  720.  
  721.     XtSetArg(args[0], XtNlabel, &value);
  722.     XtGetValues(node->resources->res_box->res_label, args, ONE);
  723.  
  724.     info.database = NULL;
  725.     XrmPutLineResource(&(info.database), value);
  726.  
  727.  
  728.     _XEditResResetStream(stream);
  729.     _XEditResPutString8(stream, info.name); /* Insert name */
  730.     _XEditResPutString8(stream, XtRString); /* insert type */
  731.  
  732.     /*
  733.      * Insert value.
  734.      */
  735.  
  736.     value = GetResourceValueForSetValues(node, &size);
  737.     _XEditResPut16(stream, size);    
  738.     for (i = 0; i < size; i++) 
  739.     _XEditResPut8(stream, value[i]);
  740.     XtFree(value);
  741.     len = stream->current - stream->top;
  742.  
  743.     /* 
  744.      * Insert the widget count, overriden later. 
  745.      */
  746.  
  747.     _XEditResPut16(stream, 0); 
  748.  
  749.     ExecuteOverAllNodes(node->tree_info->top_node,
  750.             CreateSetValuesCommand, (XtPointer) &info);
  751.     
  752.     if (info.count > 0) {
  753.     *(stream->top + len++) = info.count >> XER_NBBY; /* Set the correct */
  754.     *(stream->top + len) = info.count;               /* count. */
  755.  
  756.     SetCommand(node->tree_info->tree_widget, LocalSetValues, NULL);
  757.     }
  758.     else 
  759.     SetMessage(global_screen_data.info_label,
  760.            "ApplyResource: found no matches.");
  761.     
  762.     XrmDestroyDatabase(info.database);
  763. }
  764.  
  765. /*    Function Name: CreateSetValuesCommand
  766.  *    Description: Creates the SetValues command if this widget
  767.  *                   matches the resource string in the database.
  768.  *    Arguments: node - the current node.
  769.  *                 info_ptr - the pointer to the apply info.
  770.  *    Returns: none
  771.  */
  772.  
  773. static void
  774. CreateSetValuesCommand(node, info_ptr)
  775. WNode * node;
  776. XtPointer info_ptr;
  777. {
  778.     ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
  779.     XrmNameList name_quarks;
  780.     XrmClassList class_quarks;
  781.     char ** names, **classes;
  782.  
  783.     GetNamesAndClasses(node, &names, &classes);
  784.     name_quarks = (XrmNameList) Quarkify(names, info->name);
  785.     class_quarks = (XrmNameList) Quarkify(classes, info->class);
  786.  
  787.     if (CheckDatabase(info->database, name_quarks, class_quarks)) {
  788.     InsertWidgetFromNode(info->stream, node);
  789.     info->count++;
  790.     }
  791.  
  792.     XtFree((char *)names);
  793.     XtFree((char *)classes);
  794.     XtFree((char *)name_quarks);
  795.     XtFree((char *)class_quarks);
  796. }
  797.  
  798. /*    Function Name: ActivateResourceWidgets
  799.  *    Description: Activates all widgets that match this resource.
  800.  *    Arguments: w - UNUSED.
  801.  *                 node_ptr - the node that owns this resource box.
  802.  *                 junk - UNUSED. 
  803.  *    Returns: none.
  804.  */
  805.  
  806. /* ARGSUSED */
  807. void
  808. ActivateResourceWidgets(w, node_ptr, junk)
  809. Widget w;
  810. XtPointer node_ptr, junk;
  811. {
  812.     WNode * node = (WNode *) node_ptr;           
  813.     ApplyResourcesInfo info;
  814.     char * line;
  815.     Arg args[1];
  816.  
  817.     info.name = GetResourceName(node->resources->res_box);
  818.     info.class = "IGNORE_ME";    /* Not currently used.  */
  819.  
  820.     /* 
  821.      * Unused fields.
  822.      */
  823.  
  824.     info.count = 0;
  825.     info.stream = NULL;
  826.  
  827.     XtSetArg(args[0], XtNlabel, &line);
  828.     XtGetValues(node->resources->res_box->res_label, args, ONE);
  829.  
  830.     info.database = NULL;
  831.     XrmPutLineResource(&(info.database), line);
  832.  
  833.  
  834.     ExecuteOverAllNodes(node->tree_info->top_node,
  835.             SetOnlyMatchingWidgets, (XtPointer) &info);
  836.     
  837.     XrmDestroyDatabase(info.database);
  838. }
  839.  
  840. /*    Function Name: SetOnlyMatchingWidgets
  841.  *    Description: Activates all widgets in the tree that match this
  842.  *                   resource specifiction.
  843.  *    Arguments: node - the current node.
  844.  *                 info_ptr - the pointer to the apply info.
  845.  *    Returns: none
  846.  */
  847.  
  848. static void
  849. SetOnlyMatchingWidgets(node, info_ptr)
  850. WNode * node;
  851. XtPointer info_ptr;
  852. {
  853.     ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
  854.     XrmNameList name_quarks;
  855.     XrmClassList class_quarks;
  856.     char ** names, **classes;
  857.     Boolean state;
  858.     Arg args[1];
  859.  
  860.     GetNamesAndClasses(node, &names, &classes);
  861.     name_quarks = (XrmNameList) Quarkify(names, info->name);
  862.     class_quarks = (XrmNameList) Quarkify(classes, info->class);
  863.  
  864.     state = CheckDatabase(info->database, name_quarks, class_quarks);
  865.  
  866.     XtSetArg(args[0], XtNstate, state);
  867.     XtSetValues(node->widget, args, ONE);
  868.     TreeToggle(node->widget, (XtPointer) node, (XtPointer) state);
  869.  
  870.     XtFree((char *)names);
  871.     XtFree((char *)classes);
  872.     XtFree((char *)name_quarks);
  873.     XtFree((char *)class_quarks);
  874. }
  875.