aboutsummaryrefslogtreecommitdiffstats
path: root/RegEdit.c
diff options
context:
space:
mode:
Diffstat (limited to 'RegEdit.c')
-rw-r--r--RegEdit.c1795
1 files changed, 1795 insertions, 0 deletions
diff --git a/RegEdit.c b/RegEdit.c
new file mode 100644
index 0000000..fa01b88
--- /dev/null
+++ b/RegEdit.c
@@ -0,0 +1,1795 @@
+/* $XConsortium: RegEdit.c /main/5 1995/07/15 20:44:04 drk $ */
+/*
+ * @OPENGROUP_COPYRIGHT@
+ * COPYRIGHT NOTICE
+ * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
+ * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
+ * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
+ * the full copyright text.
+ *
+ * This software is subject to an open license. It may only be
+ * used on, with or for operating systems which are themselves open
+ * source systems. You must contact The Open Group for a license
+ * allowing distribution and sublicensing of this software on, with,
+ * or for operating systems which are not Open Source programs.
+ *
+ * See http://www.opengroup.org/openmotif/license for full
+ * details of the license agreement. Any use, reproduction, or
+ * distribution of the program constitutes recipient's acceptance of
+ * this agreement.
+ *
+ * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+ * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
+ * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+ * OR FITNESS FOR A PARTICULAR PURPOSE
+ *
+ * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+ * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+ * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+/*
+ * HISTORY
+ */
+#include <stdio.h>
+#include <Xm/XmP.h>
+#include <X11/ShellP.h>
+#include "RegEditI.h"
+
+
+/* static forward. move from global in the original Editres code */
+static void _XEditResCheckMessages();
+static void _XEditResPutString8();
+static void _XEditResPut8();
+static void _XEditResPut16();
+static void _XEditResPut32();
+static void _XEditResPutWidgetInfo();
+static void _XEditResResetStream();
+static Boolean _XEditResGet8();
+static Boolean _XEditResGet16();
+static Boolean _XEditResGetSigned16();
+static Boolean _XEditResGet32();
+static Boolean _XEditResGetString8();
+static Boolean _XEditResGetWidgetInfo();
+
+/* the only entry point here */
+void
+XmdRegisterEditres(Widget toplevel)
+{
+ XtAddEventHandler(toplevel, (EventMask) 0, TRUE,
+ _XEditResCheckMessages, NULL);
+}
+
+
+/************************************************************
+ *
+ * Dump the content of the R5 lib/Xmu/EditresCom.c module.
+ * just move global as static.
+ *
+ ************************************************************/
+
+#define _XEditResPutBool _XEditResPut8
+#define _XEditResPutResourceType _XEditResPut8
+
+/************************************************************
+ *
+ * Local structure definitions.
+ *
+ ************************************************************/
+
+typedef enum { BlockNone, BlockSetValues, BlockAll } EditresBlock;
+
+typedef struct _SetValuesEvent {
+ EditresCommand type; /* first field must be type. */
+ WidgetInfo * widgets;
+ unsigned short num_entries; /* number of set values requests. */
+ char * name;
+ char * res_type;
+ XtPointer value;
+ unsigned short value_len;
+} SetValuesEvent;
+
+typedef struct _SVErrorInfo {
+ SetValuesEvent * event;
+ ProtocolStream * stream;
+ unsigned short * count;
+ WidgetInfo * entry;
+} SVErrorInfo;
+
+typedef struct _FindChildEvent {
+ EditresCommand type; /* first field must be type. */
+ WidgetInfo * widgets;
+ short x, y;
+} FindChildEvent;
+
+typedef struct _GenericGetEvent {
+ EditresCommand type; /* first field must be type. */
+ WidgetInfo * widgets;
+ unsigned short num_entries; /* number of set values requests. */
+} GenericGetEvent, GetResEvent, GetGeomEvent;
+
+/*
+ * Things that are common to all events.
+ */
+
+typedef struct _AnyEvent {
+ EditresCommand type; /* first field must be type. */
+ WidgetInfo * widgets;
+} AnyEvent;
+
+/*
+ * The event union.
+ */
+
+typedef union _EditresEvent {
+ AnyEvent any_event;
+ SetValuesEvent set_values_event;
+ GetResEvent get_resources_event;
+ GetGeomEvent get_geometry_event;
+ FindChildEvent find_child_event;
+} EditresEvent;
+
+typedef struct _Globals {
+ EditresBlock block;
+ SVErrorInfo error_info;
+ ProtocolStream stream;
+ ProtocolStream * command_stream; /* command stream. */
+} Globals;
+
+#define CURRENT_PROTOCOL_VERSION 4L
+
+#define streq(a,b) (strcmp( (a), (b) ) == 0)
+
+static Atom res_editor_command, res_editor_protocol, client_value;
+
+static Globals globals;
+
+static void SendFailure(), SendCommand(), InsertWidget(), ExecuteCommand();
+static void FreeEvent(), ExecuteSetValues(), ExecuteGetGeometry();
+static void ExecuteGetResources();
+
+static void GetCommand();
+static void LoadResources();
+static Boolean IsChild();
+static void DumpChildren();
+static char *DumpWidgets(), *DoSetValues(), *DoFindChild();
+static char *DoGetGeometry(), *DoGetResources();
+
+/************************************************************
+ *
+ * Resource Editor Communication Code
+ *
+ ************************************************************/
+
+/* Function Name: _XEditResCheckMessages
+ * Description: This callback routine is set on all shell widgets,
+ * and checks to see if a client message event
+ * has come from the resource editor.
+ * Arguments: w - the shell widget.
+ * data - *** UNUSED ***
+ * event - The X Event that triggered this handler.
+ * cont - *** UNUSED ***.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+_XEditResCheckMessages(w, data, event, cont)
+Widget w;
+XtPointer data;
+XEvent *event;
+Boolean *cont;
+{
+ Time time;
+ ResIdent ident;
+ static Boolean first_time = FALSE;
+ static Atom res_editor, res_comm;
+ Display * dpy;
+
+ if (event->type == ClientMessage) {
+ XClientMessageEvent * c_event = (XClientMessageEvent *) event;
+ dpy = XtDisplay(w);
+
+ if (!first_time) {
+ first_time = TRUE;
+ res_editor = XInternAtom(dpy, EDITRES_NAME, False);
+ res_editor_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
+ res_editor_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM,
+ False);
+
+ /* Used in later procedures. */
+ client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
+ LoadResources(w);
+ }
+
+ if ((c_event->message_type != res_editor) ||
+ (c_event->format != EDITRES_SEND_EVENT_FORMAT))
+ return;
+
+ time = c_event->data.l[0];
+ res_comm = c_event->data.l[1];
+ ident = (ResIdent) c_event->data.l[2];
+ if (c_event->data.l[3] != CURRENT_PROTOCOL_VERSION) {
+ _XEditResResetStream(&globals.stream);
+ _XEditResPut8(&globals.stream, CURRENT_PROTOCOL_VERSION);
+ SendCommand(w, res_comm, ident, ProtocolMismatch, &globals.stream);
+ return;
+ }
+
+ XtGetSelectionValue(w, res_comm, res_editor_command,
+ GetCommand, (XtPointer) (long) ident, time);
+ }
+}
+
+/* Function Name: BuildEvent
+ * Description: Takes the info out the protocol stream an constructs
+ * the proper event structure.
+ * Arguments: w - widget to own selection, in case of error.
+ * sel - selection to send error message beck in.
+ * data - the data for the request.
+ * ident - the id number we are looking for.
+ * length - length of request.
+ * Returns: the event, or NULL.
+ */
+
+#define ERROR_MESSAGE ("Client: Improperly formatted protocol request")
+
+static EditresEvent *
+BuildEvent(w, sel, data, ident, length)
+Widget w;
+Atom sel;
+XtPointer data;
+ResIdent ident;
+unsigned long length;
+{
+ EditresEvent * event;
+ ProtocolStream alloc_stream, *stream;
+ unsigned char temp;
+ register unsigned int i;
+
+ stream = &alloc_stream; /* easier to think of it this way... */
+
+ stream->current = stream->top = (unsigned char *) data;
+ stream->size = HEADER_SIZE; /* size of header. */
+
+ /*
+ * Retrieve the Header.
+ */
+
+ if (length < HEADER_SIZE) {
+ SendFailure(w, sel, ident, Failure, ERROR_MESSAGE);
+ return(NULL);
+ }
+
+ (void) _XEditResGet8(stream, &temp);
+ if (temp != ident) /* Id's don't match, ignore request. */
+ return(NULL);
+
+ event = (EditresEvent *) XtCalloc(sizeof(EditresEvent), 1);
+
+ (void) _XEditResGet8(stream, &temp);
+ event->any_event.type = (EditresCommand) temp;
+ (void) _XEditResGet32(stream, &(stream->size));
+ stream->top = stream->current; /* reset stream to top of value.*/
+
+ /*
+ * Now retrieve the data segment.
+ */
+
+ switch(event->any_event.type) {
+ case SendWidgetTree:
+ break; /* no additional info */
+ case SetValues:
+ {
+ SetValuesEvent * sv_event = (SetValuesEvent *) event;
+
+ if ( !(_XEditResGetString8(stream, &(sv_event->name)) &&
+ _XEditResGetString8(stream, &(sv_event->res_type))))
+ {
+ goto done;
+ }
+
+ /*
+ * Since we need the value length, we have to pull the
+ * value out by hand.
+ */
+
+ if (!_XEditResGet16(stream, &(sv_event->value_len)))
+ goto done;
+
+ sv_event->value = XtMalloc(sizeof(char) *
+ (sv_event->value_len + 1));
+
+ for (i = 0; i < sv_event->value_len; i++) {
+ if (!_XEditResGet8(stream,
+ (unsigned char *) sv_event->value + i))
+ {
+ goto done;
+ }
+ }
+ ((char*)sv_event->value)[i] = '\0'; /* NULL terminate that sucker. */
+
+ if (!_XEditResGet16(stream, &(sv_event->num_entries)))
+ goto done;
+
+ sv_event->widgets = (WidgetInfo *)
+ XtCalloc(sizeof(WidgetInfo), sv_event->num_entries);
+
+ for (i = 0; i < sv_event->num_entries; i++) {
+ if (!_XEditResGetWidgetInfo(stream, sv_event->widgets + i))
+ goto done;
+ }
+ }
+ break;
+ case FindChild:
+ {
+ FindChildEvent * find_event = (FindChildEvent *) event;
+
+ find_event->widgets = (WidgetInfo *)
+ XtCalloc(sizeof(WidgetInfo), 1);
+
+ if (!(_XEditResGetWidgetInfo(stream, find_event->widgets) &&
+ _XEditResGetSigned16(stream, &(find_event->x)) &&
+ _XEditResGetSigned16(stream, &(find_event->y))))
+ {
+ goto done;
+ }
+
+ }
+ break;
+ case GetGeometry:
+ case GetResources:
+ {
+ GenericGetEvent * get_event = (GenericGetEvent *) event;
+
+ if (!_XEditResGet16(stream, &(get_event->num_entries)))
+ goto done;
+
+ get_event->widgets = (WidgetInfo *)
+ XtCalloc(sizeof(WidgetInfo), get_event->num_entries);
+ for (i = 0; i < get_event->num_entries; i++) {
+ if (!_XEditResGetWidgetInfo(stream, get_event->widgets + i))
+ goto done;
+ }
+ }
+ break;
+ default:
+ {
+ char buf[BUFSIZ];
+
+ sprintf(buf, "Unknown Protocol request %d.",event->any_event.type);
+ SendFailure(w, sel, ident, buf);
+ return(NULL);
+ }
+ }
+ return(event);
+
+ done:
+
+ SendFailure(w, sel, ident, ERROR_MESSAGE);
+ FreeEvent(event);
+ return(NULL);
+}
+
+/* Function Name: FreeEvent
+ * Description: Frees the event structure and any other pieces
+ * in it that need freeing.
+ * Arguments: event - the event to free.
+ * Returns: none.
+ */
+
+static void
+FreeEvent(event)
+EditresEvent * event;
+{
+ if (event->any_event.widgets != NULL) {
+ XtFree((char *)event->any_event.widgets->ids);
+ XtFree((char *)event->any_event.widgets);
+ }
+
+ if (event->any_event.type == SetValues) {
+ XtFree(event->set_values_event.name); /* XtFree does not free if */
+ XtFree(event->set_values_event.res_type); /* value is NULL. */
+ }
+
+ XtFree((char *)event);
+}
+
+/* Function Name: GetCommand
+ * Description: Gets the Command out of the selection asserted by the
+ * resource manager.
+ * Arguments: (See Xt XtConvertSelectionProc)
+ * data - contains the ident number for the command.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+GetCommand(w, data, selection, type, value, length, format)
+Widget w;
+XtPointer data, value;
+Atom *selection, *type;
+unsigned long *length;
+int * format;
+{
+ ResIdent ident = (ResIdent) (long) data;
+ EditresEvent * event;
+
+ if ( (*type != res_editor_protocol) || (*format != EDITRES_FORMAT) )
+ return;
+
+ if ((event = BuildEvent(w, *selection, value, ident, *length)) != NULL) {
+ ExecuteCommand(w, *selection, ident, event);
+ FreeEvent(event);
+ }
+}
+
+/* Function Name: ExecuteCommand
+ * Description: Executes a command string received from the
+ * resource editor.
+ * Arguments: w - a widget.
+ * command - the command to execute.
+ * value - the associated with the command.
+ * Returns: none.
+ *
+ * NOTES: munges str
+ */
+
+/* ARGSUSED */
+static void
+ExecuteCommand(w, sel, ident, event)
+Widget w;
+Atom sel;
+ResIdent ident;
+EditresEvent * event;
+{
+ char * (*func)();
+ char * str;
+
+ if (globals.block == BlockAll) {
+ SendFailure(w, sel, ident,
+ "This client has blocked all Editres commands.");
+ return;
+ }
+ else if ((globals.block == BlockSetValues) &&
+ (event->any_event.type == SetValues)) {
+ SendFailure(w, sel, ident,
+ "This client has blocked all SetValues requests.");
+ return;
+ }
+
+ switch(event->any_event.type) {
+ case SendWidgetTree:
+ func = DumpWidgets;
+ break;
+ case SetValues:
+ func = DoSetValues;
+ break;
+ case FindChild:
+ func = DoFindChild;
+ break;
+ case GetGeometry:
+ func = DoGetGeometry;
+ break;
+ case GetResources:
+ func = DoGetResources;
+ break;
+ default:
+ {
+ char buf[BUFSIZ];
+ sprintf(buf,"Unknown Protocol request %d.",event->any_event.type);
+ SendFailure(w, sel, ident, buf);
+ return;
+ }
+ }
+
+ _XEditResResetStream(&globals.stream);
+ if ((str = (*func)(w, event, &globals.stream)) == NULL)
+ SendCommand(w, sel, ident, PartialSuccess, &globals.stream);
+ else {
+ SendFailure(w, sel, ident, str);
+ XtFree(str);
+ }
+}
+
+/* Function Name: ConvertReturnCommand
+ * Description: Converts a selection.
+ * Arguments: w - the widget that owns the selection.
+ * selection - selection to convert.
+ * target - target type for this selection.
+ * type_ret - type of the selection.
+ * value_ret - selection value;
+ * length_ret - lenght of this selection.
+ * format_ret - the format the selection is in.
+ * Returns: True if conversion was sucessful.
+ */
+
+/* ARGSUSED */
+static Boolean
+ConvertReturnCommand(w, selection, target,
+ type_ret, value_ret, length_ret, format_ret)
+Widget w;
+Atom * selection, * target, * type_ret;
+XtPointer *value_ret;
+unsigned long * length_ret;
+int * format_ret;
+{
+ /*
+ * I assume the intrinsics give me the correct selection back.
+ */
+
+ if ((*target != client_value))
+ return(FALSE);
+
+ *type_ret = res_editor_protocol;
+ *value_ret = (XtPointer) globals.command_stream->real_top;
+ *length_ret = globals.command_stream->size + HEADER_SIZE;
+ *format_ret = EDITRES_FORMAT;
+
+ return(TRUE);
+}
+
+/* Function Name: CommandDone
+ * Description: done with the selection.
+ * Arguments: *** UNUSED ***
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+CommandDone(widget, selection, target)
+Widget widget;
+Atom *selection;
+Atom *target;
+{
+ /* Keep the toolkit from automaticaly freeing the selection value */
+}
+
+/* Function Name: SendFailure
+ * Description: Sends a failure message.
+ * Arguments: w - the widget to own the selection.
+ * sel - the selection to assert.
+ * ident - the identifier.
+ * str - the error message.
+ * Returns: none.
+ */
+
+static void
+SendFailure(w, sel, ident, str)
+Widget w;
+Atom sel;
+ResIdent ident;
+char * str;
+{
+ _XEditResResetStream(&globals.stream);
+ _XEditResPutString8(&globals.stream, str);
+ SendCommand(w, sel, ident, Failure, &globals.stream);
+}
+
+/* Function Name: BuildReturnPacket
+ * Description: Builds a return packet, given the data to send.
+ * Arguments: ident - the identifier.
+ * command - the command code.
+ * stream - the protocol stream.
+ * Returns: packet - the packet to send.
+ */
+
+static XtPointer
+BuildReturnPacket(ident, command, stream)
+ResIdent ident;
+EditresCommand command;
+ProtocolStream * stream;
+{
+ long old_alloc, old_size;
+ unsigned char * old_current;
+
+ /*
+ * We have cleverly keep enough space at the top of the header
+ * for the return protocol stream, so all we have to do is
+ * fill in the space.
+ */
+
+ /*
+ * Fool the insert routines into putting the header in the right
+ * place while being damn sure not to realloc (that would be very bad.
+ */
+
+ old_current = stream->current;
+ old_alloc = stream->alloc;
+ old_size = stream->size;
+
+ stream->current = stream->real_top;
+ stream->alloc = stream->size + (2 * HEADER_SIZE);
+
+ _XEditResPut8(stream, ident);
+ _XEditResPut8(stream, (unsigned char) command);
+ _XEditResPut32(stream, old_size);
+
+ stream->alloc = old_alloc;
+ stream->current = old_current;
+ stream->size = old_size;
+
+ return((XtPointer) stream->real_top);
+}
+
+/* Function Name: SendCommand
+ * Description: Builds a return command line.
+ * Arguments: w - the widget to own the selection.
+ * sel - the selection to assert.
+ * ident - the identifier.
+ * command - the command code.
+ * stream - the protocol stream.
+ * Returns: none.
+ */
+
+static void
+SendCommand(w, sel, ident, command, stream)
+Widget w;
+Atom sel;
+ResIdent ident;
+EditresCommand command;
+ProtocolStream * stream;
+{
+ BuildReturnPacket(ident, command, stream);
+ globals.command_stream = stream;
+
+/*
+ * I REALLY want to own the selection. Since this was not triggered
+ * by a user action, and I am the only one using this atom it is safe to
+ * use CurrentTime.
+ */
+
+ XtOwnSelection(w, sel, CurrentTime,
+ ConvertReturnCommand, NULL, CommandDone);
+}
+
+/************************************************************
+ *
+ * Generic Utility Functions.
+ *
+ ************************************************************/
+
+/* Function Name: FindChildren
+ * Description: Retuns all children (popup, normal and otherwise)
+ * of this widget
+ * Arguments: parent - the parent widget.
+ * children - the list of children.
+ * normal - return normal children.
+ * popup - return popup children.
+ * Returns: the number of children.
+ */
+
+static int
+FindChildren(parent, children, normal, popup)
+Widget parent, **children;
+Boolean normal, popup;
+{
+ CompositeWidget cw = (CompositeWidget) parent;
+ int i, num_children, current = 0;
+
+ num_children = 0;
+
+ if (XtIsWidget(parent) && popup)
+ num_children += parent->core.num_popups;
+
+ if (XtIsComposite(parent) && normal)
+ num_children += cw->composite.num_children;
+
+ if (num_children == 0) {
+ *children = NULL;
+ return(0);
+ }
+
+ *children =(Widget*) XtMalloc((Cardinal) sizeof(Widget) * num_children);
+
+ if (XtIsComposite(parent) && normal)
+ for (i = 0; i < cw->composite.num_children; i++,current++)
+ (*children)[current] = cw->composite.children[i];
+
+ if (XtIsWidget(parent) && popup)
+ for ( i = 0; i < parent->core.num_popups; i++, current++)
+ (*children)[current] = parent->core.popup_list[i];
+
+ return(num_children);
+}
+
+/* Function Name: IsChild
+ * Description: check to see of child is a child of parent.
+ * Arguments: top - the top of the tree.
+ * parent - the parent widget.
+ * child - the child.
+ * Returns: none.
+ */
+
+static Boolean
+IsChild(top, parent, child)
+Widget top, parent, child;
+{
+ int i, num_children;
+ Widget * children;
+
+ if (parent == NULL)
+ return(top == child);
+
+ num_children = FindChildren(parent, &children, TRUE, TRUE);
+
+ for (i = 0; i < num_children; i++) {
+ if (children[i] == child) {
+ XtFree((char *)children);
+ return(TRUE);
+ }
+ }
+
+ XtFree((char *)children);
+ return(FALSE);
+}
+
+/* Function Name: VerifyWidget
+ * Description: Makes sure all the widgets still exist.
+ * Arguments: w - any widget in the tree.
+ * info - the info about the widget to verify.
+ * Returns: an error message or NULL.
+ */
+
+static char *
+VerifyWidget(w, info)
+Widget w;
+WidgetInfo *info;
+{
+ Widget top;
+
+ register int count;
+ register Widget parent;
+ register unsigned long * child;
+
+ for (top = w; XtParent(top) != NULL; top = XtParent(top)) {}
+
+ parent = NULL;
+ child = info->ids;
+ count = 0;
+
+ while (TRUE) {
+ if (!IsChild(top, parent, (Widget) *child))
+ return(XtNewString("This widget no longer exists in the client."));
+
+ if (++count == info->num_widgets)
+ break;
+
+ parent = (Widget) *child++;
+ }
+
+ info->real_widget = (Widget) *child;
+ return(NULL);
+}
+
+/************************************************************
+ *
+ * Code to Perform SetValues operations.
+ *
+ ************************************************************/
+
+
+/* Function Name: DoSetValues
+ * Description: performs the setvalues requested.
+ * Arguments: w - a widget in the tree.
+ * event - the event that caused this action.
+ * stream - the protocol stream to add.
+ * Returns: NULL.
+ */
+
+static char *
+DoSetValues(w, event, stream)
+Widget w;
+EditresEvent * event;
+ProtocolStream * stream;
+{
+ char * str;
+ register unsigned i;
+ unsigned short count = 0;
+ SetValuesEvent * sv_event = (SetValuesEvent *) event;
+
+ _XEditResPut16(stream, count); /* insert 0, will be overwritten later. */
+
+ for (i = 0 ; i < sv_event->num_entries; i++) {
+ if ((str = VerifyWidget(w, &(sv_event->widgets[i]))) != NULL) {
+ _XEditResPutWidgetInfo(stream, &(sv_event->widgets[i]));
+ _XEditResPutString8(stream, str);
+ XtFree(str);
+ count++;
+ }
+ else
+ ExecuteSetValues(sv_event->widgets[i].real_widget,
+ sv_event, sv_event->widgets + i, stream, &count);
+ }
+
+ /*
+ * Overwrite the first 2 bytes with the real count.
+ */
+
+ *(stream->top) = count >> XER_NBBY;
+ *(stream->top + 1) = count;
+ return(NULL);
+}
+
+/* Function Name: HandleToolkitErrors
+ * Description: Handles X Toolkit Errors.
+ * Arguments: name - name of the error.
+ * type - type of the error.
+ * class - class of the error.
+ * msg - the default message.
+ * params, num_params - the extra parameters for this message.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+HandleToolkitErrors(name, type, class, msg, params, num_params)
+String name, type, class, msg, *params;
+Cardinal * num_params;
+{
+ SVErrorInfo * info = &globals.error_info;
+ char buf[BUFSIZ];
+
+ if ( streq(name, "unknownType") )
+ sprintf(buf, "The `%s' resource is not used by this widget.",
+ info->event->name);
+ else if ( streq(name, "noColormap") )
+ sprintf(buf, msg, params[0]);
+ else if (streq(name, "conversionFailed") || streq(name, "conversionError"))
+ {
+ if (streq(info->event->value, XtRString))
+ sprintf(buf,
+ "Could not convert the string '%s' for the `%s' resource.",
+ (char*)info->event->value, info->event->name);
+ else
+ sprintf(buf, "Could not convert the `%s' resource.",
+ info->event->name);
+ }
+ else
+ sprintf(buf, "Name: %s, Type: %s, Class: %s, Msg: %s",
+ name, type, class, msg);
+
+ /*
+ * Insert this info into the protocol stream, and update the count.
+ */
+
+ (*(info->count))++;
+ _XEditResPutWidgetInfo(info->stream, info->entry);
+ _XEditResPutString8(info->stream, buf);
+}
+
+/* Function Name: ExecuteSetValues
+ * Description: Performs a setvalues for a given command.
+ * Arguments: w - the widget to perform the set_values on.
+ * sv_event - the set values event.
+ * sv_info - the set_value info.
+ * Returns: none.
+ */
+
+static void
+ExecuteSetValues(w, sv_event, entry, stream, count)
+Widget w;
+SetValuesEvent * sv_event;
+WidgetInfo * entry;
+ProtocolStream * stream;
+unsigned short * count;
+{
+ XtErrorMsgHandler old;
+
+ SVErrorInfo * info = &globals.error_info;
+ info->event = sv_event; /* No data can be passed to */
+ info->stream = stream; /* an error handler, so we */
+ info->count = count; /* have to use a global, YUCK... */
+ info->entry = entry;
+
+ old = XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w),
+ HandleToolkitErrors);
+
+ XtVaSetValues(w, XtVaTypedArg,
+ sv_event->name, sv_event->res_type,
+ sv_event->value, sv_event->value_len,
+ NULL);
+
+ (void)XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), old);
+}
+
+
+/************************************************************
+ *
+ * Code for Creating and dumping widget tree.
+ *
+ ************************************************************/
+
+/* Function Name: DumpWidgets
+ * Description: Given a widget it builds a protocol packet
+ * containing the entire widget heirarchy.
+ * Arguments: w - a widget in the tree.
+ * event - the event that caused this action.
+ * stream - the protocol stream to add.
+ * Returns: NULL
+ */
+
+/* ARGSUSED */
+static char *
+DumpWidgets(w, event, stream)
+Widget w;
+EditresEvent * event; /* UNUSED */
+ProtocolStream * stream;
+{
+ unsigned short count = 0;
+
+ /* Find Tree's root. */
+ for ( ; XtParent(w) != NULL; w = XtParent(w)) {}
+
+ /*
+ * hold space for count, overwritten later.
+ */
+
+ _XEditResPut16(stream, (unsigned int) 0);
+
+ DumpChildren(w, stream, &count);
+
+ /*
+ * Overwrite the first 2 bytes with the real count.
+ */
+
+ *(stream->top) = count >> XER_NBBY;
+ *(stream->top + 1) = count;
+ return(NULL);
+}
+
+/* Function Name: DumpChildren
+ * Description: Adds a child's name to the list.
+ * Arguments: w - the widget to dump.
+ * stream - the stream to dump to.
+ * count - number of dumps we have performed.
+ * Returns: none.
+ */
+
+/* This is a trick/kludge. To make shared libraries happier (linking
+ * against Xmu but not linking against Xt, and apparently even work
+ * as we desire on SVR4, we need to avoid an explicit data reference
+ * to applicationShellWidgetClass. XtIsTopLevelShell is known
+ * (implementation dependent assumption!) to use a bit flag. So we
+ * go that far. Then, we test whether it is an applicationShellWidget
+ * class by looking for an explicit class name. Seems pretty safe.
+ */
+static Bool isApplicationShell(w)
+ Widget w;
+{
+ register WidgetClass c;
+
+ if (!XtIsTopLevelShell(w))
+ return False;
+ for (c = XtClass(w); c; c = c->core_class.superclass) {
+ if (!strcmp(c->core_class.class_name, "ApplicationShell"))
+ return True;
+ }
+ return False;
+}
+
+static void
+DumpChildren(w, stream, count)
+Widget w;
+ProtocolStream * stream;
+unsigned short *count;
+{
+ int i, num_children;
+ Widget *children;
+ unsigned long window;
+ char * class;
+
+ (*count)++;
+
+ InsertWidget(stream, w); /* Insert the widget into the stream. */
+
+ _XEditResPutString8(stream, XtName(w)); /* Insert name */
+
+ if (isApplicationShell(w))
+ class = ((ApplicationShellWidget) w)->application.class;
+ else
+ class = XtClass(w)->core_class.class_name;
+
+ _XEditResPutString8(stream, class); /* Insert class */
+
+ if (XtIsWidget(w))
+ if (XtIsRealized(w))
+ window = XtWindow(w);
+ else
+ window = EDITRES_IS_UNREALIZED;
+ else
+ window = EDITRES_IS_OBJECT;
+
+ _XEditResPut32(stream, window); /* Insert window id. */
+
+ /*
+ * Find children and recurse.
+ */
+
+ num_children = FindChildren(w, &children, TRUE, TRUE);
+ for (i = 0; i < num_children; i++)
+ DumpChildren(children[i], stream, count);
+
+ XtFree((char *)children);
+}
+
+/************************************************************
+ *
+ * Code for getting the geometry of widgets.
+ *
+ ************************************************************/
+
+/* Function Name: DoGetGeometry
+ * Description: retrieves the Geometry of each specified widget.
+ * Arguments: w - a widget in the tree.
+ * event - the event that caused this action.
+ * stream - the protocol stream to add.
+ * Returns: NULL
+ */
+
+static char *
+DoGetGeometry(w, event, stream)
+Widget w;
+EditresEvent * event;
+ProtocolStream * stream;
+{
+ unsigned i;
+ char * str;
+ GetGeomEvent * geom_event = (GetGeomEvent *) event;
+
+ _XEditResPut16(stream, geom_event->num_entries);
+
+ for (i = 0 ; i < geom_event->num_entries; i++) {
+
+ /*
+ * Send out the widget id.
+ */
+
+ _XEditResPutWidgetInfo(stream, &(geom_event->widgets[i]));
+ if ((str = VerifyWidget(w, &(geom_event->widgets[i]))) != NULL) {
+ _XEditResPutBool(stream, True); /* an error occured. */
+ _XEditResPutString8(stream, str); /* set message. */
+ XtFree(str);
+ }
+ else
+ ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream);
+ }
+ return(NULL);
+}
+
+/* Function Name: ExecuteGetGeometry
+ * Description: Gets the geometry for each widget specified.
+ * Arguments: w - the widget to get geom on.
+ * stream - stream to append to.
+ * Returns: True if no error occured.
+ */
+
+static void
+ExecuteGetGeometry(w, stream)
+Widget w;
+ProtocolStream * stream;
+{
+ int i;
+ Boolean mapped_when_man;
+ Dimension width, height, border_width;
+ Arg args[8];
+ Cardinal num_args = 0;
+ Position x, y;
+
+ if ( !XtIsRectObj(w) || (XtIsWidget(w) && !XtIsRealized(w)) ) {
+ _XEditResPutBool(stream, False); /* no error. */
+ _XEditResPutBool(stream, False); /* not visable. */
+ for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
+ _XEditResPut16(stream, 0);
+ return;
+ }
+
+ XtSetArg(args[num_args], XtNwidth, &width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &height); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, &border_width); num_args++;
+ XtSetArg(args[num_args], XtNmappedWhenManaged, &mapped_when_man);
+ num_args++;
+ XtGetValues(w, args, num_args);
+
+ if (!(XtIsManaged(w) && mapped_when_man) && XtIsWidget(w)) {
+ XWindowAttributes attrs;
+
+ /*
+ * The toolkit does not maintain mapping state, we have
+ * to go to the server.
+ */
+
+ if (XGetWindowAttributes(XtDisplay(w), XtWindow(w), &attrs) != 0) {
+ if (attrs.map_state != IsViewable) {
+ _XEditResPutBool(stream, False); /* no error. */
+ _XEditResPutBool(stream, False); /* not visable. */
+ for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
+ _XEditResPut16(stream, 0);
+ return;
+ }
+ }
+ else {
+ _XEditResPut8(stream, True); /* Error occured. */
+ _XEditResPutString8(stream, "XGetWindowAttributes failed.");
+ return;
+ }
+ }
+
+ XtTranslateCoords(w, -((int) border_width), -((int) border_width), &x, &y);
+
+ _XEditResPutBool(stream, False); /* no error. */
+ _XEditResPutBool(stream, True); /* Visable. */
+ _XEditResPut16(stream, x);
+ _XEditResPut16(stream, y);
+ _XEditResPut16(stream, width);
+ _XEditResPut16(stream, height);
+ _XEditResPut16(stream, border_width);
+}
+
+/************************************************************
+ *
+ * Code for executing FindChild.
+ *
+ ************************************************************/
+
+/* Function Name: PositionInChild
+ * Description: returns true if this location is in the child.
+ * Arguments: child - the child widget to check.
+ * x, y - location of point to check in the parent's
+ * coord space.
+ * Returns: TRUE if the position is in this child.
+ */
+
+static Boolean
+PositionInChild(child, x, y)
+Widget child;
+int x, y;
+{
+ Arg args[6];
+ Cardinal num;
+ Dimension width, height, border_width;
+ Position child_x, child_y;
+ Boolean mapped_when_managed;
+
+ if (!XtIsRectObj(child)) /* we must at least be a rect obj. */
+ return(FALSE);
+
+ num = 0;
+ XtSetArg(args[num], XtNmappedWhenManaged, &mapped_when_managed); num++;
+ XtSetArg(args[num], XtNwidth, &width); num++;
+ XtSetArg(args[num], XtNheight, &height); num++;
+ XtSetArg(args[num], XtNx, &child_x); num++;
+ XtSetArg(args[num], XtNy, &child_y); num++;
+ XtSetArg(args[num], XtNborderWidth, &border_width); num++;
+ XtGetValues(child, args, num);
+
+ /*
+ * The only way we will know of the widget is mapped is to see if
+ * mapped when managed is True and this is a managed child. Otherwise
+ * we will have to ask the server if this window is mapped.
+ */
+
+ if (XtIsWidget(child) && !(mapped_when_managed && XtIsManaged(child)) ) {
+ XWindowAttributes attrs;
+
+ if (XGetWindowAttributes(XtDisplay(child),
+ XtWindow(child), &attrs) != 0) {
+ /* oops */
+ }
+ else if (attrs.map_state != IsViewable)
+ return(FALSE);
+ }
+
+ return (x >= child_x) &&
+ (x <= (child_x + (Position)width + 2 * (Position)border_width)) &&
+ (y >= child_y) &&
+ (y <= (child_y + (Position)height + 2 * (Position)border_width));
+}
+
+/* Function Name: _FindChild
+ * Description: Finds the child that actually contatians the point shown.
+ * Arguments: parent - a widget that is known to contain the point
+ * specified.
+ * x, y - The point in coordinates relative to the
+ * widget specified.
+ * Returns: none.
+ */
+
+static Widget
+_FindChild(parent, x, y)
+Widget parent;
+int x, y;
+{
+ Widget * children;
+ int i = FindChildren(parent, &children, TRUE, FALSE);
+
+ while (i > 0) {
+ i--;
+
+ if (PositionInChild(children[i], x, y)) {
+ Widget child = children[i];
+
+ XtFree((char *)children);
+ return(_FindChild(child, x - child->core.x, y - child->core.y));
+ }
+ }
+
+ XtFree((char *)children);
+ return(parent);
+}
+
+/* Function Name: DoFindChild
+ * Description: finds the child that contains the location specified.
+ * Arguments: w - a widget in the tree.
+ * event - the event that caused this action.
+ * stream - the protocol stream to add.
+ * Returns: an allocated error message if something went horribly
+ * wrong and no set values were performed, else NULL.
+ */
+
+static char *
+DoFindChild(w, event, stream)
+Widget w;
+EditresEvent * event;
+ProtocolStream * stream;
+{
+ char * str;
+ Widget parent, child;
+ Position parent_x, parent_y;
+ FindChildEvent * find_event = (FindChildEvent *) event;
+
+ if ((str = VerifyWidget(w, find_event->widgets)) != NULL)
+ return(str);
+
+ parent = find_event->widgets->real_widget;
+
+ XtTranslateCoords(parent, (Position) 0, (Position) 0,
+ &parent_x, &parent_y);
+
+ child = _FindChild(parent, find_event->x - (int) parent_x,
+ find_event->y - (int) parent_y);
+
+ InsertWidget(stream, child);
+ return(NULL);
+}
+
+/************************************************************
+ *
+ * Procedures for performing GetResources.
+ *
+ ************************************************************/
+
+/* Function Name: DoGetResources
+ * Description: Gets the Resources associated with the widgets passed.
+ * Arguments: w - a widget in the tree.
+ * event - the event that caused this action.
+ * stream - the protocol stream to add.
+ * Returns: NULL
+ */
+
+static char *
+DoGetResources(w, event, stream)
+Widget w;
+EditresEvent * event;
+ProtocolStream * stream;
+{
+ unsigned int i;
+ char * str;
+ GetResEvent * res_event = (GetResEvent *) event;
+
+ _XEditResPut16(stream, res_event->num_entries); /* number of replys */
+
+ for (i = 0 ; i < res_event->num_entries; i++) {
+ /*
+ * Send out the widget id.
+ */
+ _XEditResPutWidgetInfo(stream, &(res_event->widgets[i]));
+ if ((str = VerifyWidget(w, &(res_event->widgets[i]))) != NULL) {
+ _XEditResPutBool(stream, True); /* an error occured. */
+ _XEditResPutString8(stream, str); /* set message. */
+ XtFree(str);
+ }
+ else {
+ _XEditResPutBool(stream, False); /* no error occured. */
+ ExecuteGetResources(res_event->widgets[i].real_widget,
+ stream);
+ }
+ }
+ return(NULL);
+}
+
+/* Function Name: ExecuteGetResources.
+ * Description: Gets the resources for any individual widget.
+ * Arguments: w - the widget to get resources on.
+ * stream - the protocol stream.
+ * Returns: none.
+ */
+
+static void
+ExecuteGetResources(w, stream)
+Widget w;
+ProtocolStream * stream;
+{
+ XtResourceList norm_list, cons_list;
+ Cardinal num_norm, num_cons;
+ register int i;
+
+ /*
+ * Get Normal Resources.
+ */
+
+ XtGetResourceList(XtClass(w), &norm_list, &num_norm);
+
+ if (XtParent(w) != NULL)
+ XtGetConstraintResourceList(XtClass(XtParent(w)),&cons_list,&num_cons);
+ else
+ num_cons = 0;
+
+ _XEditResPut16(stream, num_norm + num_cons); /* how many resources. */
+
+ /*
+ * Insert all the normal resources.
+ */
+
+ for ( i = 0; i < (int) num_norm; i++) {
+ _XEditResPutResourceType(stream, NormalResource);
+ _XEditResPutString8(stream, norm_list[i].resource_name);
+ _XEditResPutString8(stream, norm_list[i].resource_class);
+ _XEditResPutString8(stream, norm_list[i].resource_type);
+ }
+ XtFree((char *) norm_list);
+
+ /*
+ * Insert all the constraint resources.
+ */
+
+ if (num_cons > 0) {
+ for ( i = 0; i < (int) num_cons; i++) {
+ _XEditResPutResourceType(stream, ConstraintResource);
+ _XEditResPutString8(stream, cons_list[i].resource_name);
+ _XEditResPutString8(stream, cons_list[i].resource_class);
+ _XEditResPutString8(stream, cons_list[i].resource_type);
+ }
+ XtFree((char *) cons_list);
+ }
+}
+
+/************************************************************
+ *
+ * Code for inserting values into the protocol stream.
+ *
+ ************************************************************/
+
+/* Function Name: InsertWidget
+ * Description: Inserts the full parent heirarchy of this
+ * widget into the protocol stream as a widget list.
+ * Arguments: stream - the protocol stream.
+ * w - the widget to insert.
+ * Returns: none
+ */
+
+static void
+InsertWidget(stream, w)
+ProtocolStream * stream;
+Widget w;
+{
+ Widget temp;
+ unsigned long * widget_list;
+ register int i, num_widgets;
+
+ for (temp = w, i = 0; temp != 0; temp = XtParent(temp), i++) {}
+
+ num_widgets = i;
+ widget_list = (unsigned long *)
+ XtMalloc(sizeof(unsigned long) * num_widgets);
+
+ /*
+ * Put the widgets into the list.
+ * make sure that they are inserted in the list from parent -> child.
+ */
+
+ for (i--, temp = w; temp != NULL; temp = XtParent(temp), i--)
+ widget_list[i] = (unsigned long) temp;
+
+ _XEditResPut16(stream, num_widgets); /* insert number of widgets. */
+ for (i = 0; i < num_widgets; i++) /* insert Widgets themselves. */
+ _XEditResPut32(stream, widget_list[i]);
+
+ XtFree((char *)widget_list);
+}
+
+/************************************************************
+ *
+ * All of the following routines are public.
+ *
+ ************************************************************/
+
+/* Function Name: _XEditResPutString8
+ * Description: Inserts a string into the protocol stream.
+ * Arguments: stream - stream to insert string into.
+ * str - string to insert.
+ * Returns: none.
+ */
+
+static void
+_XEditResPutString8(stream, str)
+ProtocolStream * stream;
+char * str;
+{
+ int i, len = strlen(str);
+
+ _XEditResPut16(stream, len);
+ for (i = 0 ; i < len ; i++, str++)
+ _XEditResPut8(stream, *str);
+}
+
+/* Function Name: _XEditResPut8
+ * Description: Inserts an 8 bit integer into the protocol stream.
+ * Arguments: stream - stream to insert string into.
+ * value - value to insert.
+ * Returns: none
+ */
+
+static void
+_XEditResPut8(stream, value)
+ProtocolStream * stream;
+unsigned int value;
+{
+ unsigned char temp;
+
+ if (stream->size >= stream->alloc) {
+ stream->alloc += 100;
+ stream->real_top = (unsigned char *) XtRealloc(
+ (char *)stream->real_top,
+ stream->alloc + HEADER_SIZE);
+ stream->top = stream->real_top + HEADER_SIZE;
+ stream->current = stream->top + stream->size;
+ }
+
+ temp = (unsigned char) (value & BYTE_MASK);
+ *((stream->current)++) = temp;
+ (stream->size)++;
+}
+
+/* Function Name: _XEditResPut16
+ * Description: Inserts a 16 bit integer into the protocol stream.
+ * Arguments: stream - stream to insert string into.
+ * value - value to insert.
+ * Returns: void
+ */
+
+static void
+_XEditResPut16(stream, value)
+ProtocolStream * stream;
+unsigned int value;
+{
+ _XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK);
+ _XEditResPut8(stream, value & BYTE_MASK);
+}
+
+/* Function Name: _XEditResPut32
+ * Description: Inserts a 32 bit integer into the protocol stream.
+ * Arguments: stream - stream to insert string into.
+ * value - value to insert.
+ * Returns: void
+ */
+
+static void
+_XEditResPut32(stream, value)
+ProtocolStream * stream;
+unsigned long value;
+{
+ int i;
+
+ for (i = 3; i >= 0; i--)
+ _XEditResPut8(stream, (value >> (XER_NBBY*i)) & BYTE_MASK);
+}
+
+/* Function Name: _XEditResPutWidgetInfo
+ * Description: Inserts the widget info into the protocol stream.
+ * Arguments: stream - stream to insert widget info into.
+ * info - info to insert.
+ * Returns: none
+ */
+
+static void
+_XEditResPutWidgetInfo(stream, info)
+ProtocolStream * stream;
+WidgetInfo * info;
+{
+ unsigned int i;
+
+ _XEditResPut16(stream, info->num_widgets);
+ for (i = 0; i < info->num_widgets; i++)
+ _XEditResPut32(stream, info->ids[i]);
+}
+
+/************************************************************
+ *
+ * Code for retrieving values from the protocol stream.
+ *
+ ************************************************************/
+
+/* Function Name: _XEditResResetStream
+ * Description: resets the protocol stream
+ * Arguments: stream - the stream to reset.
+ * Returns: none.
+ */
+
+static void
+_XEditResResetStream(stream)
+ProtocolStream * stream;
+{
+ stream->current = stream->top;
+ stream->size = 0;
+ if (stream->real_top == NULL) {
+ stream->real_top = (unsigned char *) XtRealloc(
+ (char *)stream->real_top,
+ stream->alloc + HEADER_SIZE);
+ stream->top = stream->real_top + HEADER_SIZE;
+ stream->current = stream->top + stream->size;
+ }
+}
+
+/*
+ * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
+ *
+ * The only modified field if the "current" field.
+ *
+ * The only fields that must be set correctly are the "current", "top"
+ * and "size" fields.
+ */
+
+/* Function Name: _XEditResGetg8
+ * Description: Retrieves an unsigned 8 bit value
+ * from the protocol stream.
+ * Arguments: stream.
+ * val - a pointer to value to return.
+ * Returns: TRUE if sucessful.
+ */
+
+static Boolean
+_XEditResGet8(stream, val)
+ProtocolStream * stream;
+unsigned char * val;
+{
+ if (stream->size < (stream->current - stream->top))
+ return(FALSE);
+
+ *val = *((stream->current)++);
+ return(TRUE);
+}
+
+/* Function Name: _XEditResGet16
+ * Description: Retrieves an unsigned 16 bit value
+ * from the protocol stream.
+ * Arguments: stream.
+ * val - a pointer to value to return.
+ * Returns: TRUE if sucessful.
+ */
+
+static Boolean
+_XEditResGet16(stream, val)
+ProtocolStream * stream;
+unsigned short * val;
+{
+ unsigned char temp1, temp2;
+
+ if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
+ return(FALSE);
+
+ *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
+ return(TRUE);
+}
+
+/* Function Name: _XEditResGetSigned16
+ * Description: Retrieves an signed 16 bit value from the protocol stream.
+ * Arguments: stream.
+ * val - a pointer to value to return.
+ * Returns: TRUE if sucessful.
+ */
+
+static Boolean
+_XEditResGetSigned16(stream, val)
+ProtocolStream * stream;
+short * val;
+{
+ unsigned char temp1, temp2;
+
+ if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
+ return(FALSE);
+
+ if (temp1 & (1 << (XER_NBBY - 1))) { /* If the sign bit is active. */
+ *val = -1; /* store all 1's */
+ *val &= (temp1 << XER_NBBY); /* Now and in the MSB */
+ *val &= temp2; /* and LSB */
+ }
+ else
+ *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
+
+ return(TRUE);
+}
+
+/* Function Name: _XEditResGet32
+ * Description: Retrieves an unsigned 32 bit value
+ * from the protocol stream.
+ * Arguments: stream.
+ * val - a pointer to value to return.
+ * Returns: TRUE if sucessful.
+ */
+
+static Boolean
+_XEditResGet32(stream, val)
+ProtocolStream * stream;
+unsigned long * val;
+{
+ unsigned short temp1, temp2;
+
+ if ( !(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2)) )
+ return(FALSE);
+
+ *val = (((unsigned short) temp1 << (XER_NBBY * 2)) +
+ ((unsigned short) temp2));
+ return(TRUE);
+}
+
+/* Function Name: _XEditResGetString8
+ * Description: Retrieves an 8 bit string value from the protocol stream.
+ * Arguments: stream - the protocol stream
+ * str - the string to retrieve.
+ * Returns: True if retrieval was successful.
+ */
+
+static Boolean
+_XEditResGetString8(stream, str)
+ProtocolStream * stream;
+char ** str;
+{
+ unsigned short len;
+ register unsigned i;
+
+ if (!_XEditResGet16(stream, &len)) {
+ return(FALSE);
+ }
+
+ *str = XtMalloc(sizeof(char) * (len + 1));
+
+ for (i = 0; i < len; i++) {
+ if (!_XEditResGet8(stream, (unsigned char *) *str + i)) {
+ XtFree(*str);
+ *str = NULL;
+ return(FALSE);
+ }
+ }
+ (*str)[i] = '\0'; /* NULL terminate that sucker. */
+ return(TRUE);
+}
+
+/* Function Name: _XEditResGetWidgetInfo
+ * Description: Retrieves the list of widgets that follow and stores
+ * them in the widget info structure provided.
+ * Arguments: stream - the protocol stream
+ * info - the widget info struct to store into.
+ * Returns: True if retrieval was successful.
+ */
+
+static Boolean
+_XEditResGetWidgetInfo(stream, info)
+ProtocolStream * stream;
+WidgetInfo * info;
+{
+ unsigned int i;
+
+ if (!_XEditResGet16(stream, &(info->num_widgets)))
+ return(FALSE);
+
+ info->ids = (unsigned long *) XtMalloc(sizeof(long) * (info->num_widgets));
+
+ for (i = 0; i < info->num_widgets; i++) {
+ if (!_XEditResGet32(stream, info->ids + i)) {
+ XtFree((char *)info->ids);
+ info->ids = NULL;
+ return(FALSE);
+ }
+ }
+ return(TRUE);
+}
+
+/************************************************************
+ *
+ * Code for Loading the EditresBlock resource.
+ *
+ ************************************************************/
+
+/* Function Name: CvStringToBlock
+ * Description: Converts a string to an editres block value.
+ * Arguments: dpy - the display.
+ * args, num_args - **UNUSED **
+ * from_val, to_val - value to convert, and where to put result
+ * converter_data - ** UNUSED **
+ * Returns: TRUE if conversion was sucessful.
+ */
+
+/* ARGSUSED */
+static Boolean
+CvtStringToBlock(dpy, args, num_args, from_val, to_val, converter_data)
+Display * dpy;
+XrmValue * args;
+Cardinal * num_args;
+XrmValue * from_val, * to_val;
+XtPointer * converter_data;
+{
+ char ptr[BUFSIZ];
+ static EditresBlock block;
+
+/* XmuCopyISOLatin1Lowered(ptr, from_val->addr);*/
+
+
+ if (streq(ptr, "none"))
+ block = BlockNone;
+ else if (streq(ptr, "setvalues"))
+ block = BlockSetValues;
+ else if (streq(ptr, "all"))
+ block = BlockAll;
+ else {
+ Cardinal num_params = 1;
+ String params[1];
+
+ params[0] = from_val->addr;
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ "CvtStringToBlock", "unknownValue", "EditresError",
+ "Could not convert string \"%s\" to EditresBlock.",
+ params, &num_params);
+ return(FALSE);
+ }
+
+ if (to_val->addr != NULL) {
+ if (to_val->size < sizeof(EditresBlock)) {
+ to_val->size = sizeof(EditresBlock);
+ return(FALSE);
+ }
+ *(EditresBlock *)(to_val->addr) = block;
+ }
+ else
+ to_val->addr = (XtPointer) block;
+
+ to_val->size = sizeof(EditresBlock);
+ return(TRUE);
+}
+
+#define XtREditresBlock ("EditresBlock")
+
+/* Function Name: LoadResources
+ * Description: Loads a global resource the determines of this
+ * application should allow Editres requests.
+ * Arguments: w - any widget in the tree.
+ * Returns: none.
+ */
+
+static void
+LoadResources(w)
+Widget w;
+{
+ static XtResource resources[] = {
+ {"editresBlock", "EditresBlock", XtREditresBlock, sizeof(EditresBlock),
+ XtOffsetOf(Globals, block), XtRImmediate, (XtPointer) BlockNone}
+ };
+
+ for (; XtParent(w) != NULL; w = XtParent(w)) {}
+
+ XtAppSetTypeConverter(XtWidgetToApplicationContext(w),
+ XtRString, XtREditresBlock, CvtStringToBlock,
+ NULL, (Cardinal) 0, XtCacheAll, NULL);
+
+ XtGetApplicationResources( w, (caddr_t) &globals, resources,
+ XtNumber(resources), NULL, (Cardinal) 0);
+}
+
+