1 /* $XConsortium: RegEdit.c /main/5 1995/07/15 20:44:04 drk $ */
2 /*
3 * @OPENGROUP_COPYRIGHT@
4 * COPYRIGHT NOTICE
5 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
6 * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
7 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
8 * the full copyright text.
9 *
10 * This software is subject to an open license. It may only be
11 * used on, with or for operating systems which are themselves open
12 * source systems. You must contact The Open Group for a license
13 * allowing distribution and sublicensing of this software on, with,
14 * or for operating systems which are not Open Source programs.
15 *
16 * See http://www.opengroup.org/openmotif/license for full
17 * details of the license agreement. Any use, reproduction, or
18 * distribution of the program constitutes recipient's acceptance of
19 * this agreement.
20 *
21 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
22 * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23 * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
24 * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
25 * OR FITNESS FOR A PARTICULAR PURPOSE
26 *
27 * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
28 * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
34 * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGES.
36 *
37 */
38 /*
39 * HISTORY
40 */
41 #include <stdio.h>
42 #include <Xm/XmP.h>
43 #include <X11/ShellP.h>
44 #include "RegEditI.h"
45
46
47 /* static forward. move from global in the original Editres code */
48 static void _XEditResCheckMessages();
49 static void _XEditResPutString8();
50 static void _XEditResPut8();
51 static void _XEditResPut16();
52 static void _XEditResPut32();
53 static void _XEditResPutWidgetInfo();
54 static void _XEditResResetStream();
55 static Boolean _XEditResGet8();
56 static Boolean _XEditResGet16();
57 static Boolean _XEditResGetSigned16();
58 static Boolean _XEditResGet32();
59 static Boolean _XEditResGetString8();
60 static Boolean _XEditResGetWidgetInfo();
61
62 /* the only entry point here */
63 void
64 XmdRegisterEditres(Widget toplevel)
65 {
66 XtAddEventHandler(toplevel, (EventMask) 0, TRUE,
67 _XEditResCheckMessages, NULL);
68 }
69
70
71 /************************************************************
72 *
73 * Dump the content of the R5 lib/Xmu/EditresCom.c module.
74 * just move global as static.
75 *
76 ************************************************************/
77
78 #define _XEditResPutBool _XEditResPut8
79 #define _XEditResPutResourceType _XEditResPut8
80
81 /************************************************************
82 *
83 * Local structure definitions.
84 *
85 ************************************************************/
86
87 typedef enum { BlockNone, BlockSetValues, BlockAll } EditresBlock;
88
89 typedef struct _SetValuesEvent {
90 EditresCommand type; /* first field must be type. */
91 WidgetInfo * widgets;
92 unsigned short num_entries; /* number of set values requests. */
93 char * name;
94 char * res_type;
95 XtPointer value;
96 unsigned short value_len;
97 } SetValuesEvent;
98
99 typedef struct _SVErrorInfo {
100 SetValuesEvent * event;
101 ProtocolStream * stream;
102 unsigned short * count;
103 WidgetInfo * entry;
104 } SVErrorInfo;
105
106 typedef struct _FindChildEvent {
107 EditresCommand type; /* first field must be type. */
108 WidgetInfo * widgets;
109 short x, y;
110 } FindChildEvent;
111
112 typedef struct _GenericGetEvent {
113 EditresCommand type; /* first field must be type. */
114 WidgetInfo * widgets;
115 unsigned short num_entries; /* number of set values requests. */
116 } GenericGetEvent, GetResEvent, GetGeomEvent;
117
118 /*
119 * Things that are common to all events.
120 */
121
122 typedef struct _AnyEvent {
123 EditresCommand type; /* first field must be type. */
124 WidgetInfo * widgets;
125 } AnyEvent;
126
127 /*
128 * The event union.
129 */
130
131 typedef union _EditresEvent {
132 AnyEvent any_event;
133 SetValuesEvent set_values_event;
134 GetResEvent get_resources_event;
135 GetGeomEvent get_geometry_event;
136 FindChildEvent find_child_event;
137 } EditresEvent;
138
139 typedef struct _Globals {
140 EditresBlock block;
141 SVErrorInfo error_info;
142 ProtocolStream stream;
143 ProtocolStream * command_stream; /* command stream. */
144 } Globals;
145
146 #define CURRENT_PROTOCOL_VERSION 4L
147
148 #define streq(a,b) (strcmp( (a), (b) ) == 0)
149
150 static Atom res_editor_command, res_editor_protocol, client_value;
151
152 static Globals globals;
153
154 static void SendFailure(), SendCommand(), InsertWidget(), ExecuteCommand();
155 static void FreeEvent(), ExecuteSetValues(), ExecuteGetGeometry();
156 static void ExecuteGetResources();
157
158 static void GetCommand();
159 static void LoadResources();
160 static Boolean IsChild();
161 static void DumpChildren();
162 static char *DumpWidgets(), *DoSetValues(), *DoFindChild();
163 static char *DoGetGeometry(), *DoGetResources();
164
165 /************************************************************
166 *
167 * Resource Editor Communication Code
168 *
169 ************************************************************/
170
171 /* Function Name: _XEditResCheckMessages
172 * Description: This callback routine is set on all shell widgets,
173 * and checks to see if a client message event
174 * has come from the resource editor.
175 * Arguments: w - the shell widget.
176 * data - *** UNUSED ***
177 * event - The X Event that triggered this handler.
178 * cont - *** UNUSED ***.
179 * Returns: none.
180 */
181
182 /* ARGSUSED */
183 static void
184 _XEditResCheckMessages(w, data, event, cont)
185 Widget w;
186 XtPointer data;
187 XEvent *event;
188 Boolean *cont;
189 {
190 Time time;
191 ResIdent ident;
192 static Boolean first_time = FALSE;
193 static Atom res_editor, res_comm;
194 Display * dpy;
195
196 if (event->type == ClientMessage) {
197 XClientMessageEvent * c_event = (XClientMessageEvent *) event;
198 dpy = XtDisplay(w);
199
200 if (!first_time) {
201 first_time = TRUE;
202 res_editor = XInternAtom(dpy, EDITRES_NAME, False);
203 res_editor_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
204 res_editor_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM,
205 False);
206
207 /* Used in later procedures. */
208 client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
209 LoadResources(w);
210 }
211
212 if ((c_event->message_type != res_editor) ||
213 (c_event->format != EDITRES_SEND_EVENT_FORMAT))
214 return;
215
216 time = c_event->data.l[0];
217 res_comm = c_event->data.l[1];
218 ident = (ResIdent) c_event->data.l[2];
219 if (c_event->data.l[3] != CURRENT_PROTOCOL_VERSION) {
220 _XEditResResetStream(&globals.stream);
221 _XEditResPut8(&globals.stream, CURRENT_PROTOCOL_VERSION);
222 SendCommand(w, res_comm, ident, ProtocolMismatch, &globals.stream);
223 return;
224 }
225
226 XtGetSelectionValue(w, res_comm, res_editor_command,
227 GetCommand, (XtPointer) (long) ident, time);
228 }
229 }
230
231 /* Function Name: BuildEvent
232 * Description: Takes the info out the protocol stream an constructs
233 * the proper event structure.
234 * Arguments: w - widget to own selection, in case of error.
235 * sel - selection to send error message beck in.
236 * data - the data for the request.
237 * ident - the id number we are looking for.
238 * length - length of request.
239 * Returns: the event, or NULL.
240 */
241
242 #define ERROR_MESSAGE ("Client: Improperly formatted protocol request")
243
244 static EditresEvent *
245 BuildEvent(w, sel, data, ident, length)
246 Widget w;
247 Atom sel;
248 XtPointer data;
249 ResIdent ident;
250 unsigned long length;
251 {
252 EditresEvent * event;
253 ProtocolStream alloc_stream, *stream;
254 unsigned char temp;
255 register unsigned int i;
256
257 stream = &alloc_stream; /* easier to think of it this way... */
258
259 stream->current = stream->top = (unsigned char *) data;
260 stream->size = HEADER_SIZE; /* size of header. */
261
262 /*
263 * Retrieve the Header.
264 */
265
266 if (length < HEADER_SIZE) {
267 SendFailure(w, sel, ident, Failure, ERROR_MESSAGE);
268 return(NULL);
269 }
270
271 (void) _XEditResGet8(stream, &temp);
272 if (temp != ident) /* Id's don't match, ignore request. */
273 return(NULL);
274
275 event = (EditresEvent *) XtCalloc(sizeof(EditresEvent), 1);
276
277 (void) _XEditResGet8(stream, &temp);
278 event->any_event.type = (EditresCommand) temp;
279 (void) _XEditResGet32(stream, &(stream->size));
280 stream->top = stream->current; /* reset stream to top of value.*/
281
282 /*
283 * Now retrieve the data segment.
284 */
285
286 switch(event->any_event.type) {
287 case SendWidgetTree:
288 break; /* no additional info */
289 case SetValues:
290 {
291 SetValuesEvent * sv_event = (SetValuesEvent *) event;
292
293 if ( !(_XEditResGetString8(stream, &(sv_event->name)) &&
294 _XEditResGetString8(stream, &(sv_event->res_type))))
295 {
296 goto done;
297 }
298
299 /*
300 * Since we need the value length, we have to pull the
301 * value out by hand.
302 */
303
304 if (!_XEditResGet16(stream, &(sv_event->value_len)))
305 goto done;
306
307 sv_event->value = XtMalloc(sizeof(char) *
308 (sv_event->value_len + 1));
309
310 for (i = 0; i < sv_event->value_len; i++) {
311 if (!_XEditResGet8(stream,
312 (unsigned char *) sv_event->value + i))
313 {
314 goto done;
315 }
316 }
317 ((char*)sv_event->value)[i] = '\0'; /* NULL terminate that sucker. */
318
319 if (!_XEditResGet16(stream, &(sv_event->num_entries)))
320 goto done;
321
322 sv_event->widgets = (WidgetInfo *)
323 XtCalloc(sizeof(WidgetInfo), sv_event->num_entries);
324
325 for (i = 0; i < sv_event->num_entries; i++) {
326 if (!_XEditResGetWidgetInfo(stream, sv_event->widgets + i))
327 goto done;
328 }
329 }
330 break;
331 case FindChild:
332 {
333 FindChildEvent * find_event = (FindChildEvent *) event;
334
335 find_event->widgets = (WidgetInfo *)
336 XtCalloc(sizeof(WidgetInfo), 1);
337
338 if (!(_XEditResGetWidgetInfo(stream, find_event->widgets) &&
339 _XEditResGetSigned16(stream, &(find_event->x)) &&
340 _XEditResGetSigned16(stream, &(find_event->y))))
341 {
342 goto done;
343 }
344
345 }
346 break;
347 case GetGeometry:
348 case GetResources:
349 {
350 GenericGetEvent * get_event = (GenericGetEvent *) event;
351
352 if (!_XEditResGet16(stream, &(get_event->num_entries)))
353 goto done;
354
355 get_event->widgets = (WidgetInfo *)
356 XtCalloc(sizeof(WidgetInfo), get_event->num_entries);
357 for (i = 0; i < get_event->num_entries; i++) {
358 if (!_XEditResGetWidgetInfo(stream, get_event->widgets + i))
359 goto done;
360 }
361 }
362 break;
363 default:
364 {
365 char buf[BUFSIZ];
366
367 sprintf(buf, "Unknown Protocol request %d.",event->any_event.type);
368 SendFailure(w, sel, ident, buf);
369 return(NULL);
370 }
371 }
372 return(event);
373
374 done:
375
376 SendFailure(w, sel, ident, ERROR_MESSAGE);
377 FreeEvent(event);
378 return(NULL);
379 }
380
381 /* Function Name: FreeEvent
382 * Description: Frees the event structure and any other pieces
383 * in it that need freeing.
384 * Arguments: event - the event to free.
385 * Returns: none.
386 */
387
388 static void
389 FreeEvent(event)
390 EditresEvent * event;
391 {
392 if (event->any_event.widgets != NULL) {
393 XtFree((char *)event->any_event.widgets->ids);
394 XtFree((char *)event->any_event.widgets);
395 }
396
397 if (event->any_event.type == SetValues) {
398 XtFree(event->set_values_event.name); /* XtFree does not free if */
399 XtFree(event->set_values_event.res_type); /* value is NULL. */
400 }
401
402 XtFree((char *)event);
403 }
404
405 /* Function Name: GetCommand
406 * Description: Gets the Command out of the selection asserted by the
407 * resource manager.
408 * Arguments: (See Xt XtConvertSelectionProc)
409 * data - contains the ident number for the command.
410 * Returns: none.
411 */
412
413 /* ARGSUSED */
414 static void
415 GetCommand(w, data, selection, type, value, length, format)
416 Widget w;
417 XtPointer data, value;
418 Atom *selection, *type;
419 unsigned long *length;
420 int * format;
421 {
422 ResIdent ident = (ResIdent) (long) data;
423 EditresEvent * event;
424
425 if ( (*type != res_editor_protocol) || (*format != EDITRES_FORMAT) )
426 return;
427
428 if ((event = BuildEvent(w, *selection, value, ident, *length)) != NULL) {
429 ExecuteCommand(w, *selection, ident, event);
430 FreeEvent(event);
431 }
432 }
433
434 /* Function Name: ExecuteCommand
435 * Description: Executes a command string received from the
436 * resource editor.
437 * Arguments: w - a widget.
438 * command - the command to execute.
439 * value - the associated with the command.
440 * Returns: none.
441 *
442 * NOTES: munges str
443 */
444
445 /* ARGSUSED */
446 static void
447 ExecuteCommand(w, sel, ident, event)
448 Widget w;
449 Atom sel;
450 ResIdent ident;
451 EditresEvent * event;
452 {
453 char * (*func)();
454 char * str;
455
456 if (globals.block == BlockAll) {
457 SendFailure(w, sel, ident,
458 "This client has blocked all Editres commands.");
459 return;
460 }
461 else if ((globals.block == BlockSetValues) &&
462 (event->any_event.type == SetValues)) {
463 SendFailure(w, sel, ident,
464 "This client has blocked all SetValues requests.");
465 return;
466 }
467
468 switch(event->any_event.type) {
469 case SendWidgetTree:
470 func = DumpWidgets;
471 break;
472 case SetValues:
473 func = DoSetValues;
474 break;
475 case FindChild:
476 func = DoFindChild;
477 break;
478 case GetGeometry:
479 func = DoGetGeometry;
480 break;
481 case GetResources:
482 func = DoGetResources;
483 break;
484 default:
485 {
486 char buf[BUFSIZ];
487 sprintf(buf,"Unknown Protocol request %d.",event->any_event.type);
488 SendFailure(w, sel, ident, buf);
489 return;
490 }
491 }
492
493 _XEditResResetStream(&globals.stream);
494 if ((str = (*func)(w, event, &globals.stream)) == NULL)
495 SendCommand(w, sel, ident, PartialSuccess, &globals.stream);
496 else {
497 SendFailure(w, sel, ident, str);
498 XtFree(str);
499 }
500 }
501
502 /* Function Name: ConvertReturnCommand
503 * Description: Converts a selection.
504 * Arguments: w - the widget that owns the selection.
505 * selection - selection to convert.
506 * target - target type for this selection.
507 * type_ret - type of the selection.
508 * value_ret - selection value;
509 * length_ret - lenght of this selection.
510 * format_ret - the format the selection is in.
511 * Returns: True if conversion was sucessful.
512 */
513
514 /* ARGSUSED */
515 static Boolean
516 ConvertReturnCommand(w, selection, target,
517 type_ret, value_ret, length_ret, format_ret)
518 Widget w;
519 Atom * selection, * target, * type_ret;
520 XtPointer *value_ret;
521 unsigned long * length_ret;
522 int * format_ret;
523 {
524 /*
525 * I assume the intrinsics give me the correct selection back.
526 */
527
528 if ((*target != client_value))
529 return(FALSE);
530
531 *type_ret = res_editor_protocol;
532 *value_ret = (XtPointer) globals.command_stream->real_top;
533 *length_ret = globals.command_stream->size + HEADER_SIZE;
534 *format_ret = EDITRES_FORMAT;
535
536 return(TRUE);
537 }
538
539 /* Function Name: CommandDone
540 * Description: done with the selection.
541 * Arguments: *** UNUSED ***
542 * Returns: none.
543 */
544
545 /* ARGSUSED */
546 static void
547 CommandDone(widget, selection, target)
548 Widget widget;
549 Atom *selection;
550 Atom *target;
551 {
552 /* Keep the toolkit from automaticaly freeing the selection value */
553 }
554
555 /* Function Name: SendFailure
556 * Description: Sends a failure message.
557 * Arguments: w - the widget to own the selection.
558 * sel - the selection to assert.
559 * ident - the identifier.
560 * str - the error message.
561 * Returns: none.
562 */
563
564 static void
565 SendFailure(w, sel, ident, str)
566 Widget w;
567 Atom sel;
568 ResIdent ident;
569 char * str;
570 {
571 _XEditResResetStream(&globals.stream);
572 _XEditResPutString8(&globals.stream, str);
573 SendCommand(w, sel, ident, Failure, &globals.stream);
574 }
575
576 /* Function Name: BuildReturnPacket
577 * Description: Builds a return packet, given the data to send.
578 * Arguments: ident - the identifier.
579 * command - the command code.
580 * stream - the protocol stream.
581 * Returns: packet - the packet to send.
582 */
583
584 static XtPointer
585 BuildReturnPacket(ident, command, stream)
586 ResIdent ident;
587 EditresCommand command;
588 ProtocolStream * stream;
589 {
590 long old_alloc, old_size;
591 unsigned char * old_current;
592
593 /*
594 * We have cleverly keep enough space at the top of the header
595 * for the return protocol stream, so all we have to do is
596 * fill in the space.
597 */
598
599 /*
600 * Fool the insert routines into putting the header in the right
601 * place while being damn sure not to realloc (that would be very bad.
602 */
603
604 old_current = stream->current;
605 old_alloc = stream->alloc;
606 old_size = stream->size;
607
608 stream->current = stream->real_top;
609 stream->alloc = stream->size + (2 * HEADER_SIZE);
610
611 _XEditResPut8(stream, ident);
612 _XEditResPut8(stream, (unsigned char) command);
613 _XEditResPut32(stream, old_size);
614
615 stream->alloc = old_alloc;
616 stream->current = old_current;
617 stream->size = old_size;
618
619 return((XtPointer) stream->real_top);
620 }
621
622 /* Function Name: SendCommand
623 * Description: Builds a return command line.
624 * Arguments: w - the widget to own the selection.
625 * sel - the selection to assert.
626 * ident - the identifier.
627 * command - the command code.
628 * stream - the protocol stream.
629 * Returns: none.
630 */
631
632 static void
633 SendCommand(w, sel, ident, command, stream)
634 Widget w;
635 Atom sel;
636 ResIdent ident;
637 EditresCommand command;
638 ProtocolStream * stream;
639 {
640 BuildReturnPacket(ident, command, stream);
641 globals.command_stream = stream;
642
643 /*
644 * I REALLY want to own the selection. Since this was not triggered
645 * by a user action, and I am the only one using this atom it is safe to
646 * use CurrentTime.
647 */
648
649 XtOwnSelection(w, sel, CurrentTime,
650 ConvertReturnCommand, NULL, CommandDone);
651 }
652
653 /************************************************************
654 *
655 * Generic Utility Functions.
656 *
657 ************************************************************/
658
659 /* Function Name: FindChildren
660 * Description: Retuns all children (popup, normal and otherwise)
661 * of this widget
662 * Arguments: parent - the parent widget.
663 * children - the list of children.
664 * normal - return normal children.
665 * popup - return popup children.
666 * Returns: the number of children.
667 */
668
669 static int
670 FindChildren(parent, children, normal, popup)
671 Widget parent, **children;
672 Boolean normal, popup;
673 {
674 CompositeWidget cw = (CompositeWidget) parent;
675 int i, num_children, current = 0;
676
677 num_children = 0;
678
679 if (XtIsWidget(parent) && popup)
680 num_children += parent->core.num_popups;
681
682 if (XtIsComposite(parent) && normal)
683 num_children += cw->composite.num_children;
684
685 if (num_children == 0) {
686 *children = NULL;
687 return(0);
688 }
689
690 *children =(Widget*) XtMalloc((Cardinal) sizeof(Widget) * num_children);
691
692 if (XtIsComposite(parent) && normal)
693 for (i = 0; i < cw->composite.num_children; i++,current++)
694 (*children)[current] = cw->composite.children[i];
695
696 if (XtIsWidget(parent) && popup)
697 for ( i = 0; i < parent->core.num_popups; i++, current++)
698 (*children)[current] = parent->core.popup_list[i];
699
700 return(num_children);
701 }
702
703 /* Function Name: IsChild
704 * Description: check to see of child is a child of parent.
705 * Arguments: top - the top of the tree.
706 * parent - the parent widget.
707 * child - the child.
708 * Returns: none.
709 */
710
711 static Boolean
712 IsChild(top, parent, child)
713 Widget top, parent, child;
714 {
715 int i, num_children;
716 Widget * children;
717
718 if (parent == NULL)
719 return(top == child);
720
721 num_children = FindChildren(parent, &children, TRUE, TRUE);
722
723 for (i = 0; i < num_children; i++) {
724 if (children[i] == child) {
725 XtFree((char *)children);
726 return(TRUE);
727 }
728 }
729
730 XtFree((char *)children);
731 return(FALSE);
732 }
733
734 /* Function Name: VerifyWidget
735 * Description: Makes sure all the widgets still exist.
736 * Arguments: w - any widget in the tree.
737 * info - the info about the widget to verify.
738 * Returns: an error message or NULL.
739 */
740
741 static char *
742 VerifyWidget(w, info)
743 Widget w;
744 WidgetInfo *info;
745 {
746 Widget top;
747
748 register int count;
749 register Widget parent;
750 register unsigned long * child;
751
752 for (top = w; XtParent(top) != NULL; top = XtParent(top)) {}
753
754 parent = NULL;
755 child = info->ids;
756 count = 0;
757
758 while (TRUE) {
759 if (!IsChild(top, parent, (Widget) *child))
760 return(XtNewString("This widget no longer exists in the client."));
761
762 if (++count == info->num_widgets)
763 break;
764
765 parent = (Widget) *child++;
766 }
767
768 info->real_widget = (Widget) *child;
769 return(NULL);
770 }
771
772 /************************************************************
773 *
774 * Code to Perform SetValues operations.
775 *
776 ************************************************************/
777
778
779 /* Function Name: DoSetValues
780 * Description: performs the setvalues requested.
781 * Arguments: w - a widget in the tree.
782 * event - the event that caused this action.
783 * stream - the protocol stream to add.
784 * Returns: NULL.
785 */
786
787 static char *
788 DoSetValues(w, event, stream)
789 Widget w;
790 EditresEvent * event;
791 ProtocolStream * stream;
792 {
793 char * str;
794 register unsigned i;
795 unsigned short count = 0;
796 SetValuesEvent * sv_event = (SetValuesEvent *) event;
797
798 _XEditResPut16(stream, count); /* insert 0, will be overwritten later. */
799
800 for (i = 0 ; i < sv_event->num_entries; i++) {
801 if ((str = VerifyWidget(w, &(sv_event->widgets[i]))) != NULL) {
802 _XEditResPutWidgetInfo(stream, &(sv_event->widgets[i]));
803 _XEditResPutString8(stream, str);
804 XtFree(str);
805 count++;
806 }
807 else
808 ExecuteSetValues(sv_event->widgets[i].real_widget,
809 sv_event, sv_event->widgets + i, stream, &count);
810 }
811
812 /*
813 * Overwrite the first 2 bytes with the real count.
814 */
815
816 *(stream->top) = count >> XER_NBBY;
817 *(stream->top + 1) = count;
818 return(NULL);
819 }
820
821 /* Function Name: HandleToolkitErrors
822 * Description: Handles X Toolkit Errors.
823 * Arguments: name - name of the error.
824 * type - type of the error.
825 * class - class of the error.
826 * msg - the default message.
827 * params, num_params - the extra parameters for this message.
828 * Returns: none.
829 */
830
831 /* ARGSUSED */
832 static void
833 HandleToolkitErrors(name, type, class, msg, params, num_params)
834 String name, type, class, msg, *params;
835 Cardinal * num_params;
836 {
837 SVErrorInfo * info = &globals.error_info;
838 char buf[BUFSIZ];
839
840 if ( streq(name, "unknownType") )
841 sprintf(buf, "The `%s' resource is not used by this widget.",
842 info->event->name);
843 else if ( streq(name, "noColormap") )
844 sprintf(buf, msg, params[0]);
845 else if (streq(name, "conversionFailed") || streq(name, "conversionError"))
846 {
847 if (streq(info->event->value, XtRString))
848 sprintf(buf,
849 "Could not convert the string '%s' for the `%s' resource.",
850 (char*)info->event->value, info->event->name);
851 else
852 sprintf(buf, "Could not convert the `%s' resource.",
853 info->event->name);
854 }
855 else
856 sprintf(buf, "Name: %s, Type: %s, Class: %s, Msg: %s",
857 name, type, class, msg);
858
859 /*
860 * Insert this info into the protocol stream, and update the count.
861 */
862
863 (*(info->count))++;
864 _XEditResPutWidgetInfo(info->stream, info->entry);
865 _XEditResPutString8(info->stream, buf);
866 }
867
868 /* Function Name: ExecuteSetValues
869 * Description: Performs a setvalues for a given command.
870 * Arguments: w - the widget to perform the set_values on.
871 * sv_event - the set values event.
872 * sv_info - the set_value info.
873 * Returns: none.
874 */
875
876 static void
877 ExecuteSetValues(w, sv_event, entry, stream, count)
878 Widget w;
879 SetValuesEvent * sv_event;
880 WidgetInfo * entry;
881 ProtocolStream * stream;
882 unsigned short * count;
883 {
884 XtErrorMsgHandler old;
885
886 SVErrorInfo * info = &globals.error_info;
887 info->event = sv_event; /* No data can be passed to */
888 info->stream = stream; /* an error handler, so we */
889 info->count = count; /* have to use a global, YUCK... */
890 info->entry = entry;
891
892 old = XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w),
893 HandleToolkitErrors);
894
895 XtVaSetValues(w, XtVaTypedArg,
896 sv_event->name, sv_event->res_type,
897 sv_event->value, sv_event->value_len,
898 NULL);
899
900 (void)XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), old);
901 }
902
903
904 /************************************************************
905 *
906 * Code for Creating and dumping widget tree.
907 *
908 ************************************************************/
909
910 /* Function Name: DumpWidgets
911 * Description: Given a widget it builds a protocol packet
912 * containing the entire widget heirarchy.
913 * Arguments: w - a widget in the tree.
914 * event - the event that caused this action.
915 * stream - the protocol stream to add.
916 * Returns: NULL
917 */
918
919 /* ARGSUSED */
920 static char *
921 DumpWidgets(w, event, stream)
922 Widget w;
923 EditresEvent * event; /* UNUSED */
924 ProtocolStream * stream;
925 {
926 unsigned short count = 0;
927
928 /* Find Tree's root. */
929 for ( ; XtParent(w) != NULL; w = XtParent(w)) {}
930
931 /*
932 * hold space for count, overwritten later.
933 */
934
935 _XEditResPut16(stream, (unsigned int) 0);
936
937 DumpChildren(w, stream, &count);
938
939 /*
940 * Overwrite the first 2 bytes with the real count.
941 */
942
943 *(stream->top) = count >> XER_NBBY;
944 *(stream->top + 1) = count;
945 return(NULL);
946 }
947
948 /* Function Name: DumpChildren
949 * Description: Adds a child's name to the list.
950 * Arguments: w - the widget to dump.
951 * stream - the stream to dump to.
952 * count - number of dumps we have performed.
953 * Returns: none.
954 */
955
956 /* This is a trick/kludge. To make shared libraries happier (linking
957 * against Xmu but not linking against Xt, and apparently even work
958 * as we desire on SVR4, we need to avoid an explicit data reference
959 * to applicationShellWidgetClass. XtIsTopLevelShell is known
960 * (implementation dependent assumption!) to use a bit flag. So we
961 * go that far. Then, we test whether it is an applicationShellWidget
962 * class by looking for an explicit class name. Seems pretty safe.
963 */
964 static Bool isApplicationShell(w)
965 Widget w;
966 {
967 register WidgetClass c;
968
969 if (!XtIsTopLevelShell(w))
970 return False;
971 for (c = XtClass(w); c; c = c->core_class.superclass) {
972 if (!strcmp(c->core_class.class_name, "ApplicationShell"))
973 return True;
974 }
975 return False;
976 }
977
978 static void
979 DumpChildren(w, stream, count)
980 Widget w;
981 ProtocolStream * stream;
982 unsigned short *count;
983 {
984 int i, num_children;
985 Widget *children;
986 unsigned long window;
987 char * class;
988
989 (*count)++;
990
991 InsertWidget(stream, w); /* Insert the widget into the stream. */
992
993 _XEditResPutString8(stream, XtName(w)); /* Insert name */
994
995 if (isApplicationShell(w))
996 class = ((ApplicationShellWidget) w)->application.class;
997 else
998 class = XtClass(w)->core_class.class_name;
999
1000 _XEditResPutString8(stream, class); /* Insert class */
1001
1002 if (XtIsWidget(w))
1003 if (XtIsRealized(w))
1004 window = XtWindow(w);
1005 else
1006 window = EDITRES_IS_UNREALIZED;
1007 else
1008 window = EDITRES_IS_OBJECT;
1009
1010 _XEditResPut32(stream, window); /* Insert window id. */
1011
1012 /*
1013 * Find children and recurse.
1014 */
1015
1016 num_children = FindChildren(w, &children, TRUE, TRUE);
1017 for (i = 0; i < num_children; i++)
1018 DumpChildren(children[i], stream, count);
1019
1020 XtFree((char *)children);
1021 }
1022
1023 /************************************************************
1024 *
1025 * Code for getting the geometry of widgets.
1026 *
1027 ************************************************************/
1028
1029 /* Function Name: DoGetGeometry
1030 * Description: retrieves the Geometry of each specified widget.
1031 * Arguments: w - a widget in the tree.
1032 * event - the event that caused this action.
1033 * stream - the protocol stream to add.
1034 * Returns: NULL
1035 */
1036
1037 static char *
1038 DoGetGeometry(w, event, stream)
1039 Widget w;
1040 EditresEvent * event;
1041 ProtocolStream * stream;
1042 {
1043 unsigned i;
1044 char * str;
1045 GetGeomEvent * geom_event = (GetGeomEvent *) event;
1046
1047 _XEditResPut16(stream, geom_event->num_entries);
1048
1049 for (i = 0 ; i < geom_event->num_entries; i++) {
1050
1051 /*
1052 * Send out the widget id.
1053 */
1054
1055 _XEditResPutWidgetInfo(stream, &(geom_event->widgets[i]));
1056 if ((str = VerifyWidget(w, &(geom_event->widgets[i]))) != NULL) {
1057 _XEditResPutBool(stream, True); /* an error occured. */
1058 _XEditResPutString8(stream, str); /* set message. */
1059 XtFree(str);
1060 }
1061 else
1062 ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream);
1063 }
1064 return(NULL);
1065 }
1066
1067 /* Function Name: ExecuteGetGeometry
1068 * Description: Gets the geometry for each widget specified.
1069 * Arguments: w - the widget to get geom on.
1070 * stream - stream to append to.
1071 * Returns: True if no error occured.
1072 */
1073
1074 static void
1075 ExecuteGetGeometry(w, stream)
1076 Widget w;
1077 ProtocolStream * stream;
1078 {
1079 int i;
1080 Boolean mapped_when_man;
1081 Dimension width, height, border_width;
1082 Arg args[8];
1083 Cardinal num_args = 0;
1084 Position x, y;
1085
1086 if ( !XtIsRectObj(w) || (XtIsWidget(w) && !XtIsRealized(w)) ) {
1087 _XEditResPutBool(stream, False); /* no error. */
1088 _XEditResPutBool(stream, False); /* not visable. */
1089 for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
1090 _XEditResPut16(stream, 0);
1091 return;
1092 }
1093
1094 XtSetArg(args[num_args], XtNwidth, &width); num_args++;
1095 XtSetArg(args[num_args], XtNheight, &height); num_args++;
1096 XtSetArg(args[num_args], XtNborderWidth, &border_width); num_args++;
1097 XtSetArg(args[num_args], XtNmappedWhenManaged, &mapped_when_man);
1098 num_args++;
1099 XtGetValues(w, args, num_args);
1100
1101 if (!(XtIsManaged(w) && mapped_when_man) && XtIsWidget(w)) {
1102 XWindowAttributes attrs;
1103
1104 /*
1105 * The toolkit does not maintain mapping state, we have
1106 * to go to the server.
1107 */
1108
1109 if (XGetWindowAttributes(XtDisplay(w), XtWindow(w), &attrs) != 0) {
1110 if (attrs.map_state != IsViewable) {
1111 _XEditResPutBool(stream, False); /* no error. */
1112 _XEditResPutBool(stream, False); /* not visable. */
1113 for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
1114 _XEditResPut16(stream, 0);
1115 return;
1116 }
1117 }
1118 else {
1119 _XEditResPut8(stream, True); /* Error occured. */
1120 _XEditResPutString8(stream, "XGetWindowAttributes failed.");
1121 return;
1122 }
1123 }
1124
1125 XtTranslateCoords(w, -((int) border_width), -((int) border_width), &x, &y);
1126
1127 _XEditResPutBool(stream, False); /* no error. */
1128 _XEditResPutBool(stream, True); /* Visable. */
1129 _XEditResPut16(stream, x);
1130 _XEditResPut16(stream, y);
1131 _XEditResPut16(stream, width);
1132 _XEditResPut16(stream, height);
1133 _XEditResPut16(stream, border_width);
1134 }
1135
1136 /************************************************************
1137 *
1138 * Code for executing FindChild.
1139 *
1140 ************************************************************/
1141
1142 /* Function Name: PositionInChild
1143 * Description: returns true if this location is in the child.
1144 * Arguments: child - the child widget to check.
1145 * x, y - location of point to check in the parent's
1146 * coord space.
1147 * Returns: TRUE if the position is in this child.
1148 */
1149
1150 static Boolean
1151 PositionInChild(child, x, y)
1152 Widget child;
1153 int x, y;
1154 {
1155 Arg args[6];
1156 Cardinal num;
1157 Dimension width, height, border_width;
1158 Position child_x, child_y;
1159 Boolean mapped_when_managed;
1160
1161 if (!XtIsRectObj(child)) /* we must at least be a rect obj. */
1162 return(FALSE);
1163
1164 num = 0;
1165 XtSetArg(args[num], XtNmappedWhenManaged, &mapped_when_managed); num++;
1166 XtSetArg(args[num], XtNwidth, &width); num++;
1167 XtSetArg(args[num], XtNheight, &height); num++;
1168 XtSetArg(args[num], XtNx, &child_x); num++;
1169 XtSetArg(args[num], XtNy, &child_y); num++;
1170 XtSetArg(args[num], XtNborderWidth, &border_width); num++;
1171 XtGetValues(child, args, num);
1172
1173 /*
1174 * The only way we will know of the widget is mapped is to see if
1175 * mapped when managed is True and this is a managed child. Otherwise
1176 * we will have to ask the server if this window is mapped.
1177 */
1178
1179 if (XtIsWidget(child) && !(mapped_when_managed && XtIsManaged(child)) ) {
1180 XWindowAttributes attrs;
1181
1182 if (XGetWindowAttributes(XtDisplay(child),
1183 XtWindow(child), &attrs) != 0) {
1184 /* oops */
1185 }
1186 else if (attrs.map_state != IsViewable)
1187 return(FALSE);
1188 }
1189
1190 return (x >= child_x) &&
1191 (x <= (child_x + (Position)width + 2 * (Position)border_width)) &&
1192 (y >= child_y) &&
1193 (y <= (child_y + (Position)height + 2 * (Position)border_width));
1194 }
1195
1196 /* Function Name: _FindChild
1197 * Description: Finds the child that actually contatians the point shown.
1198 * Arguments: parent - a widget that is known to contain the point
1199 * specified.
1200 * x, y - The point in coordinates relative to the
1201 * widget specified.
1202 * Returns: none.
1203 */
1204
1205 static Widget
1206 _FindChild(parent, x, y)
1207 Widget parent;
1208 int x, y;
1209 {
1210 Widget * children;
1211 int i = FindChildren(parent, &children, TRUE, FALSE);
1212
1213 while (i > 0) {
1214 i--;
1215
1216 if (PositionInChild(children[i], x, y)) {
1217 Widget child = children[i];
1218
1219 XtFree((char *)children);
1220 return(_FindChild(child, x - child->core.x, y - child->core.y));
1221 }
1222 }
1223
1224 XtFree((char *)children);
1225 return(parent);
1226 }
1227
1228 /* Function Name: DoFindChild
1229 * Description: finds the child that contains the location specified.
1230 * Arguments: w - a widget in the tree.
1231 * event - the event that caused this action.
1232 * stream - the protocol stream to add.
1233 * Returns: an allocated error message if something went horribly
1234 * wrong and no set values were performed, else NULL.
1235 */
1236
1237 static char *
1238 DoFindChild(w, event, stream)
1239 Widget w;
1240 EditresEvent * event;
1241 ProtocolStream * stream;
1242 {
1243 char * str;
1244 Widget parent, child;
1245 Position parent_x, parent_y;
1246 FindChildEvent * find_event = (FindChildEvent *) event;
1247
1248 if ((str = VerifyWidget(w, find_event->widgets)) != NULL)
1249 return(str);
1250
1251 parent = find_event->widgets->real_widget;
1252
1253 XtTranslateCoords(parent, (Position) 0, (Position) 0,
1254 &parent_x, &parent_y);
1255
1256 child = _FindChild(parent, find_event->x - (int) parent_x,
1257 find_event->y - (int) parent_y);
1258
1259 InsertWidget(stream, child);
1260 return(NULL);
1261 }
1262
1263 /************************************************************
1264 *
1265 * Procedures for performing GetResources.
1266 *
1267 ************************************************************/
1268
1269 /* Function Name: DoGetResources
1270 * Description: Gets the Resources associated with the widgets passed.
1271 * Arguments: w - a widget in the tree.
1272 * event - the event that caused this action.
1273 * stream - the protocol stream to add.
1274 * Returns: NULL
1275 */
1276
1277 static char *
1278 DoGetResources(w, event, stream)
1279 Widget w;
1280 EditresEvent * event;
1281 ProtocolStream * stream;
1282 {
1283 unsigned int i;
1284 char * str;
1285 GetResEvent * res_event = (GetResEvent *) event;
1286
1287 _XEditResPut16(stream, res_event->num_entries); /* number of replys */
1288
1289 for (i = 0 ; i < res_event->num_entries; i++) {
1290 /*
1291 * Send out the widget id.
1292 */
1293 _XEditResPutWidgetInfo(stream, &(res_event->widgets[i]));
1294 if ((str = VerifyWidget(w, &(res_event->widgets[i]))) != NULL) {
1295 _XEditResPutBool(stream, True); /* an error occured. */
1296 _XEditResPutString8(stream, str); /* set message. */
1297 XtFree(str);
1298 }
1299 else {
1300 _XEditResPutBool(stream, False); /* no error occured. */
1301 ExecuteGetResources(res_event->widgets[i].real_widget,
1302 stream);
1303 }
1304 }
1305 return(NULL);
1306 }
1307
1308 /* Function Name: ExecuteGetResources.
1309 * Description: Gets the resources for any individual widget.
1310 * Arguments: w - the widget to get resources on.
1311 * stream - the protocol stream.
1312 * Returns: none.
1313 */
1314
1315 static void
1316 ExecuteGetResources(w, stream)
1317 Widget w;
1318 ProtocolStream * stream;
1319 {
1320 XtResourceList norm_list, cons_list;
1321 Cardinal num_norm, num_cons;
1322 register int i;
1323
1324 /*
1325 * Get Normal Resources.
1326 */
1327
1328 XtGetResourceList(XtClass(w), &norm_list, &num_norm);
1329
1330 if (XtParent(w) != NULL)
1331 XtGetConstraintResourceList(XtClass(XtParent(w)),&cons_list,&num_cons);
1332 else
1333 num_cons = 0;
1334
1335 _XEditResPut16(stream, num_norm + num_cons); /* how many resources. */
1336
1337 /*
1338 * Insert all the normal resources.
1339 */
1340
1341 for ( i = 0; i < (int) num_norm; i++) {
1342 _XEditResPutResourceType(stream, NormalResource);
1343 _XEditResPutString8(stream, norm_list[i].resource_name);
1344 _XEditResPutString8(stream, norm_list[i].resource_class);
1345 _XEditResPutString8(stream, norm_list[i].resource_type);
1346 }
1347 XtFree((char *) norm_list);
1348
1349 /*
1350 * Insert all the constraint resources.
1351 */
1352
1353 if (num_cons > 0) {
1354 for ( i = 0; i < (int) num_cons; i++) {
1355 _XEditResPutResourceType(stream, ConstraintResource);
1356 _XEditResPutString8(stream, cons_list[i].resource_name);
1357 _XEditResPutString8(stream, cons_list[i].resource_class);
1358 _XEditResPutString8(stream, cons_list[i].resource_type);
1359 }
1360 XtFree((char *) cons_list);
1361 }
1362 }
1363
1364 /************************************************************
1365 *
1366 * Code for inserting values into the protocol stream.
1367 *
1368 ************************************************************/
1369
1370 /* Function Name: InsertWidget
1371 * Description: Inserts the full parent heirarchy of this
1372 * widget into the protocol stream as a widget list.
1373 * Arguments: stream - the protocol stream.
1374 * w - the widget to insert.
1375 * Returns: none
1376 */
1377
1378 static void
1379 InsertWidget(stream, w)
1380 ProtocolStream * stream;
1381 Widget w;
1382 {
1383 Widget temp;
1384 unsigned long * widget_list;
1385 register int i, num_widgets;
1386
1387 for (temp = w, i = 0; temp != 0; temp = XtParent(temp), i++) {}
1388
1389 num_widgets = i;
1390 widget_list = (unsigned long *)
1391 XtMalloc(sizeof(unsigned long) * num_widgets);
1392
1393 /*
1394 * Put the widgets into the list.
1395 * make sure that they are inserted in the list from parent -> child.
1396 */
1397
1398 for (i--, temp = w; temp != NULL; temp = XtParent(temp), i--)
1399 widget_list[i] = (unsigned long) temp;
1400
1401 _XEditResPut16(stream, num_widgets); /* insert number of widgets. */
1402 for (i = 0; i < num_widgets; i++) /* insert Widgets themselves. */
1403 _XEditResPut32(stream, widget_list[i]);
1404
1405 XtFree((char *)widget_list);
1406 }
1407
1408 /************************************************************
1409 *
1410 * All of the following routines are public.
1411 *
1412 ************************************************************/
1413
1414 /* Function Name: _XEditResPutString8
1415 * Description: Inserts a string into the protocol stream.
1416 * Arguments: stream - stream to insert string into.
1417 * str - string to insert.
1418 * Returns: none.
1419 */
1420
1421 static void
1422 _XEditResPutString8(stream, str)
1423 ProtocolStream * stream;
1424 char * str;
1425 {
1426 int i, len = strlen(str);
1427
1428 _XEditResPut16(stream, len);
1429 for (i = 0 ; i < len ; i++, str++)
1430 _XEditResPut8(stream, *str);
1431 }
1432
1433 /* Function Name: _XEditResPut8
1434 * Description: Inserts an 8 bit integer into the protocol stream.
1435 * Arguments: stream - stream to insert string into.
1436 * value - value to insert.
1437 * Returns: none
1438 */
1439
1440 static void
1441 _XEditResPut8(stream, value)
1442 ProtocolStream * stream;
1443 unsigned int value;
1444 {
1445 unsigned char temp;
1446
1447 if (stream->size >= stream->alloc) {
1448 stream->alloc += 100;
1449 stream->real_top = (unsigned char *) XtRealloc(
1450 (char *)stream->real_top,
1451 stream->alloc + HEADER_SIZE);
1452 stream->top = stream->real_top + HEADER_SIZE;
1453 stream->current = stream->top + stream->size;
1454 }
1455
1456 temp = (unsigned char) (value & BYTE_MASK);
1457 *((stream->current)++) = temp;
1458 (stream->size)++;
1459 }
1460
1461 /* Function Name: _XEditResPut16
1462 * Description: Inserts a 16 bit integer into the protocol stream.
1463 * Arguments: stream - stream to insert string into.
1464 * value - value to insert.
1465 * Returns: void
1466 */
1467
1468 static void
1469 _XEditResPut16(stream, value)
1470 ProtocolStream * stream;
1471 unsigned int value;
1472 {
1473 _XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK);
1474 _XEditResPut8(stream, value & BYTE_MASK);
1475 }
1476
1477 /* Function Name: _XEditResPut32
1478 * Description: Inserts a 32 bit integer into the protocol stream.
1479 * Arguments: stream - stream to insert string into.
1480 * value - value to insert.
1481 * Returns: void
1482 */
1483
1484 static void
1485 _XEditResPut32(stream, value)
1486 ProtocolStream * stream;
1487 unsigned long value;
1488 {
1489 int i;
1490
1491 for (i = 3; i >= 0; i--)
1492 _XEditResPut8(stream, (value >> (XER_NBBY*i)) & BYTE_MASK);
1493 }
1494
1495 /* Function Name: _XEditResPutWidgetInfo
1496 * Description: Inserts the widget info into the protocol stream.
1497 * Arguments: stream - stream to insert widget info into.
1498 * info - info to insert.
1499 * Returns: none
1500 */
1501
1502 static void
1503 _XEditResPutWidgetInfo(stream, info)
1504 ProtocolStream * stream;
1505 WidgetInfo * info;
1506 {
1507 unsigned int i;
1508
1509 _XEditResPut16(stream, info->num_widgets);
1510 for (i = 0; i < info->num_widgets; i++)
1511 _XEditResPut32(stream, info->ids[i]);
1512 }
1513
1514 /************************************************************
1515 *
1516 * Code for retrieving values from the protocol stream.
1517 *
1518 ************************************************************/
1519
1520 /* Function Name: _XEditResResetStream
1521 * Description: resets the protocol stream
1522 * Arguments: stream - the stream to reset.
1523 * Returns: none.
1524 */
1525
1526 static void
1527 _XEditResResetStream(stream)
1528 ProtocolStream * stream;
1529 {
1530 stream->current = stream->top;
1531 stream->size = 0;
1532 if (stream->real_top == NULL) {
1533 stream->real_top = (unsigned char *) XtRealloc(
1534 (char *)stream->real_top,
1535 stream->alloc + HEADER_SIZE);
1536 stream->top = stream->real_top + HEADER_SIZE;
1537 stream->current = stream->top + stream->size;
1538 }
1539 }
1540
1541 /*
1542 * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
1543 *
1544 * The only modified field if the "current" field.
1545 *
1546 * The only fields that must be set correctly are the "current", "top"
1547 * and "size" fields.
1548 */
1549
1550 /* Function Name: _XEditResGetg8
1551 * Description: Retrieves an unsigned 8 bit value
1552 * from the protocol stream.
1553 * Arguments: stream.
1554 * val - a pointer to value to return.
1555 * Returns: TRUE if sucessful.
1556 */
1557
1558 static Boolean
1559 _XEditResGet8(stream, val)
1560 ProtocolStream * stream;
1561 unsigned char * val;
1562 {
1563 if (stream->size < (stream->current - stream->top))
1564 return(FALSE);
1565
1566 *val = *((stream->current)++);
1567 return(TRUE);
1568 }
1569
1570 /* Function Name: _XEditResGet16
1571 * Description: Retrieves an unsigned 16 bit value
1572 * from the protocol stream.
1573 * Arguments: stream.
1574 * val - a pointer to value to return.
1575 * Returns: TRUE if sucessful.
1576 */
1577
1578 static Boolean
1579 _XEditResGet16(stream, val)
1580 ProtocolStream * stream;
1581 unsigned short * val;
1582 {
1583 unsigned char temp1, temp2;
1584
1585 if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
1586 return(FALSE);
1587
1588 *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
1589 return(TRUE);
1590 }
1591
1592 /* Function Name: _XEditResGetSigned16
1593 * Description: Retrieves an signed 16 bit value from the protocol stream.
1594 * Arguments: stream.
1595 * val - a pointer to value to return.
1596 * Returns: TRUE if sucessful.
1597 */
1598
1599 static Boolean
1600 _XEditResGetSigned16(stream, val)
1601 ProtocolStream * stream;
1602 short * val;
1603 {
1604 unsigned char temp1, temp2;
1605
1606 if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
1607 return(FALSE);
1608
1609 if (temp1 & (1 << (XER_NBBY - 1))) { /* If the sign bit is active. */
1610 *val = -1; /* store all 1's */
1611 *val &= (temp1 << XER_NBBY); /* Now and in the MSB */
1612 *val &= temp2; /* and LSB */
1613 }
1614 else
1615 *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
1616
1617 return(TRUE);
1618 }
1619
1620 /* Function Name: _XEditResGet32
1621 * Description: Retrieves an unsigned 32 bit value
1622 * from the protocol stream.
1623 * Arguments: stream.
1624 * val - a pointer to value to return.
1625 * Returns: TRUE if sucessful.
1626 */
1627
1628 static Boolean
1629 _XEditResGet32(stream, val)
1630 ProtocolStream * stream;
1631 unsigned long * val;
1632 {
1633 unsigned short temp1, temp2;
1634
1635 if ( !(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2)) )
1636 return(FALSE);
1637
1638 *val = (((unsigned short) temp1 << (XER_NBBY * 2)) +
1639 ((unsigned short) temp2));
1640 return(TRUE);
1641 }
1642
1643 /* Function Name: _XEditResGetString8
1644 * Description: Retrieves an 8 bit string value from the protocol stream.
1645 * Arguments: stream - the protocol stream
1646 * str - the string to retrieve.
1647 * Returns: True if retrieval was successful.
1648 */
1649
1650 static Boolean
1651 _XEditResGetString8(stream, str)
1652 ProtocolStream * stream;
1653 char ** str;
1654 {
1655 unsigned short len;
1656 register unsigned i;
1657
1658 if (!_XEditResGet16(stream, &len)) {
1659 return(FALSE);
1660 }
1661
1662 *str = XtMalloc(sizeof(char) * (len + 1));
1663
1664 for (i = 0; i < len; i++) {
1665 if (!_XEditResGet8(stream, (unsigned char *) *str + i)) {
1666 XtFree(*str);
1667 *str = NULL;
1668 return(FALSE);
1669 }
1670 }
1671 (*str)[i] = '\0'; /* NULL terminate that sucker. */
1672 return(TRUE);
1673 }
1674
1675 /* Function Name: _XEditResGetWidgetInfo
1676 * Description: Retrieves the list of widgets that follow and stores
1677 * them in the widget info structure provided.
1678 * Arguments: stream - the protocol stream
1679 * info - the widget info struct to store into.
1680 * Returns: True if retrieval was successful.
1681 */
1682
1683 static Boolean
1684 _XEditResGetWidgetInfo(stream, info)
1685 ProtocolStream * stream;
1686 WidgetInfo * info;
1687 {
1688 unsigned int i;
1689
1690 if (!_XEditResGet16(stream, &(info->num_widgets)))
1691 return(FALSE);
1692
1693 info->ids = (unsigned long *) XtMalloc(sizeof(long) * (info->num_widgets));
1694
1695 for (i = 0; i < info->num_widgets; i++) {
1696 if (!_XEditResGet32(stream, info->ids + i)) {
1697 XtFree((char *)info->ids);
1698 info->ids = NULL;
1699 return(FALSE);
1700 }
1701 }
1702 return(TRUE);
1703 }
1704
1705 /************************************************************
1706 *
1707 * Code for Loading the EditresBlock resource.
1708 *
1709 ************************************************************/
1710
1711 /* Function Name: CvStringToBlock
1712 * Description: Converts a string to an editres block value.
1713 * Arguments: dpy - the display.
1714 * args, num_args - **UNUSED **
1715 * from_val, to_val - value to convert, and where to put result
1716 * converter_data - ** UNUSED **
1717 * Returns: TRUE if conversion was sucessful.
1718 */
1719
1720 /* ARGSUSED */
1721 static Boolean
1722 CvtStringToBlock(dpy, args, num_args, from_val, to_val, converter_data)
1723 Display * dpy;
1724 XrmValue * args;
1725 Cardinal * num_args;
1726 XrmValue * from_val, * to_val;
1727 XtPointer * converter_data;
1728 {
1729 char ptr[BUFSIZ];
1730 static EditresBlock block;
1731
1732 /* XmuCopyISOLatin1Lowered(ptr, from_val->addr);*/
1733
1734
1735 if (streq(ptr, "none"))
1736 block = BlockNone;
1737 else if (streq(ptr, "setvalues"))
1738 block = BlockSetValues;
1739 else if (streq(ptr, "all"))
1740 block = BlockAll;
1741 else {
1742 Cardinal num_params = 1;
1743 String params[1];
1744
1745 params[0] = from_val->addr;
1746 XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1747 "CvtStringToBlock", "unknownValue", "EditresError",
1748 "Could not convert string \"%s\" to EditresBlock.",
1749 params, &num_params);
1750 return(FALSE);
1751 }
1752
1753 if (to_val->addr != NULL) {
1754 if (to_val->size < sizeof(EditresBlock)) {
1755 to_val->size = sizeof(EditresBlock);
1756 return(FALSE);
1757 }
1758 *(EditresBlock *)(to_val->addr) = block;
1759 }
1760 else
1761 to_val->addr = (XtPointer) block;
1762
1763 to_val->size = sizeof(EditresBlock);
1764 return(TRUE);
1765 }
1766
1767 #define XtREditresBlock ("EditresBlock")
1768
1769 /* Function Name: LoadResources
1770 * Description: Loads a global resource the determines of this
1771 * application should allow Editres requests.
1772 * Arguments: w - any widget in the tree.
1773 * Returns: none.
1774 */
1775
1776 static void
1777 LoadResources(w)
1778 Widget w;
1779 {
1780 static XtResource resources[] = {
1781 {"editresBlock", "EditresBlock", XtREditresBlock, sizeof(EditresBlock),
1782 XtOffsetOf(Globals, block), XtRImmediate, (XtPointer) BlockNone}
1783 };
1784
1785 for (; XtParent(w) != NULL; w = XtParent(w)) {}
1786
1787 XtAppSetTypeConverter(XtWidgetToApplicationContext(w),
1788 XtRString, XtREditresBlock, CvtStringToBlock,
1789 NULL, (Cardinal) 0, XtCacheAll, NULL);
1790
1791 XtGetApplicationResources( w, (caddr_t) &globals, resources,
1792 XtNumber(resources), NULL, (Cardinal) 0);
1793 }
1794
1795
1796
|
This page was automatically generated by the
LXR engine.
|