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