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