home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / l / libxtgeo.zip / libgeo17 / X11 / Xmu / EditresCom.c < prev   
C/C++ Source or Header  |  1992-10-06  |  47KB  |  1,757 lines

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