Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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.