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