diff options
Diffstat (limited to 'libXmu/src/EditresCom.c')
-rw-r--r-- | libXmu/src/EditresCom.c | 4427 |
1 files changed, 2213 insertions, 2214 deletions
diff --git a/libXmu/src/EditresCom.c b/libXmu/src/EditresCom.c index 51ac24895..aeef24099 100644 --- a/libXmu/src/EditresCom.c +++ b/libXmu/src/EditresCom.c @@ -1,2214 +1,2213 @@ -/* $Xorg: EditresCom.c,v 1.4 2001/02/09 02:03:52 xorgcvs Exp $ */ - -/* - -Copyright 1989, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ -/* $XFree86: xc/lib/Xmu/EditresCom.c,v 1.21 2003/10/24 15:44:05 tsi Exp $ */ - -/* - * Author: Chris D. Peterson, Dave Sternlicht, MIT X Consortium - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <X11/IntrinsicP.h> /* To get into the composite and core widget - structures. */ -#include <X11/ObjectP.h> /* For XtIs<Classname> macros. */ -#include <X11/StringDefs.h> /* for XtRString. */ -#include <X11/ShellP.h> /* for Application Shell Widget class. */ - -#include <X11/Xatom.h> -#include <X11/Xos.h> /* for strcpy declaration */ -#include <X11/Xfuncs.h> -#include <X11/Xmu/EditresP.h> -#include <X11/Xmd.h> -#include <X11/Xmu/CharSet.h> -#include <X11/Xmu/SysUtil.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define _XEditResPutBool _XEditResPut8 -#define _XEditResPutResourceType _XEditResPut8 - -/* - * Types - */ -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 _GetValuesEvent { - EditresCommand type; /* first field must be type */ - WidgetInfo *widgets; - unsigned short num_entries; /* number of get values requests */ - char *name; -} GetValuesEvent; - -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; - -/* - * 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 */ -#if defined(LONG64) || defined(WORD64) - unsigned long base_address; -#endif -} Globals; - -#define CURRENT_PROTOCOL_VERSION 5L - -#define streq(a,b) (strcmp((a), (b)) == 0) - -/* - * Prototypes - */ -static Widget _FindChild(Widget, int, int); -static void _XEditresGetStringValues(Widget, Arg*, int); -static XtPointer BuildReturnPacket(ResIdent, EditResError, ProtocolStream*); -static void CommandDone(Widget, Atom*, Atom*); -static Boolean ConvertReturnCommand(Widget, Atom*, Atom*, Atom*, XtPointer*, - unsigned long*, int*); -static Boolean CvtStringToBlock(Display*, XrmValue*, Cardinal*, - XrmValue*, XrmValue*, XtPointer*); -static EditresEvent *BuildEvent(Widget, Atom, XtPointer, ResIdent, - unsigned long); -static char *DoFindChild(Widget, EditresEvent*, ProtocolStream*); -static char *DoGetGeometry(Widget, EditresEvent*, ProtocolStream*); -static char *DoGetResources(Widget, EditresEvent*, ProtocolStream*); -static char *DoSetValues(Widget, EditresEvent*, ProtocolStream*); -static void DumpChildren(Widget, ProtocolStream*, unsigned short*); -static char *DumpValues(Widget, EditresEvent*, ProtocolStream*); -static char *DumpWidgets(Widget, EditresEvent*, ProtocolStream*); -static void ExecuteCommand(Widget, Atom, ResIdent, EditresEvent*); -static void ExecuteGetGeometry(Widget, ProtocolStream*); -static void ExecuteGetResources(Widget w, ProtocolStream *stream); -static void ExecuteSetValues(Widget, SetValuesEvent*, WidgetInfo*, - ProtocolStream*, unsigned short*); -static void FreeEvent(EditresEvent*); -static void GetCommand(Widget w, XtPointer, Atom*, Atom*, XtPointer, - unsigned long*, int*); -static void HandleToolkitErrors(String, String, String, String, - String*, Cardinal*); -static void InsertWidget(ProtocolStream*, Widget); -static Bool IsChild(Widget, Widget, Widget); -static Bool isApplicationShell(Widget); -static void LoadResources(Widget); -static Bool PositionInChild(Widget, int, int); -static int qcmp_widget_list(register _Xconst void*, register _Xconst void*); -static void SendCommand(Widget, Atom, ResIdent, EditResError, - ProtocolStream*); -static void SendFailure(Widget, Atom, ResIdent, char*); -static char *VerifyWidget(Widget, WidgetInfo*); - -/* - * External - */ -void _XEditResCheckMessages(Widget, XtPointer, XEvent*, Boolean*); - -/* - * Initialization - */ -static Atom res_editor_command, res_editor_protocol, client_value; -static Globals globals; - -/************************************************************ - * Resource Editor Communication Code - ************************************************************/ -/* - * Function: - * _XEditResCheckMessages - * - * Parameters: - * data - unused - * event - The X Event that triggered this handler - * cont - unused - * - * 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. - */ -/*ARGSUSED*/ -void -_XEditResCheckMessages(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) - { - Atom atoms[4]; - static char *names[] = { - EDITRES_NAME, EDITRES_COMMAND_ATOM, - EDITRES_PROTOCOL_ATOM, EDITRES_CLIENT_VALUE - }; - - first_time = True; - XInternAtoms(dpy, names, 4, False, atoms); - res_editor = atoms[0]; - res_editor_command = atoms[1]; - res_editor_protocol = atoms[2]; - /* Used in later procedures */ - client_value = atoms[3]; - 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, (unsigned int) 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: - * BuildEvent - * - * Parameters: - * 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 - * - * Description: - * Takes the info out the protocol stream an constructs - * the proper event structure. - * - * Returns: - * the event, or NULL - */ -#if defined(ERROR_MESSAGE) -#undef ERROR_MESSAGE -#endif -#define ERROR_MESSAGE "Client: Improperly formatted protocol request" -static EditresEvent * -BuildEvent(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; - 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, 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'; - - 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; - case GetValues: - { - GetValuesEvent *gv_event = (GetValuesEvent *)event; - - _XEditResGetString8(stream, &gv_event->name); - _XEditResGet16(stream, &gv_event->num_entries); - gv_event->widgets = (WidgetInfo *) - XtCalloc(sizeof(WidgetInfo), gv_event->num_entries); - _XEditResGetWidgetInfo(stream, gv_event->widgets); - } - break; - default: - { - char buf[BUFSIZ]; - - XmuSnprintf(buf, sizeof(buf), - "Unknown Protocol request %d.", event->any_event.type); - SendFailure(w, sel, ident, buf); - FreeEvent(event); - return (NULL); - } - } - - return (event); - - done: - SendFailure(w, sel, ident, ERROR_MESSAGE); - FreeEvent(event); - return (NULL); -} - -/* - * Function: - * FreeEvent - * - * Parameters: - * event - event to free - * - * Description: - * Frees the event structure and any other pieces in it that need freeing. - */ -static void -FreeEvent(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(event->set_values_event.res_type); - } - - XtFree((char *)event); -} - -/* - * Function: - * GetCommand - * - * Parameters: - * (See Xt XtConvertSelectionProc) - * data - contains the ident number for the command - * - * Description: - * Gets the Command out of the selection asserted by the resource manager. - */ -/*ARGSUSED*/ -static void -GetCommand(Widget w, XtPointer data, Atom *selection, Atom *type, - XtPointer value, 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: - * ExecuteCommand - * - * Parameters: - * w - widget - * command - the command to execute - * value - the associated with the command - * - * Description: - * Executes a command string received from the resource editor. - */ -/*ARGSUSED*/ -static void -ExecuteCommand(Widget w, Atom sel, ResIdent ident, EditresEvent *event) -{ - char *(*func)(Widget, EditresEvent*, ProtocolStream*); - 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: -#if defined(LONG64) || defined(WORD64) - globals.base_address = (unsigned long)w & 0xFFFFFFFF00000000; -#endif - func = DumpWidgets; - break; - case SetValues: - func = DoSetValues; - break; - case FindChild: - func = DoFindChild; - break; - case GetGeometry: - func = DoGetGeometry; - break; - case GetResources: - func = DoGetResources; - break; - case GetValues: - func = DumpValues; - break; - default: - { - char buf[BUFSIZ]; - - XmuSnprintf(buf, sizeof(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); -} - -/* - * Function: - * ConvertReturnCommand - * - * Parameters: - * 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 - * - * Description: - * Converts a selection - * - * Returns: - * True if conversion was sucessful - */ -/*ARGSUSED*/ -static Boolean -ConvertReturnCommand(Widget w, Atom *selection, Atom *target, Atom *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: - * CommandDone - * - * Parameters: - * widget - unused - * selection - unused - * target - unused - * - * Description: - * done with the selection - */ -/*ARGSUSED*/ -static void -CommandDone(Widget widget, Atom *selection, Atom *target) -{ - /* Keep the toolkit from automaticaly freeing the selection value */ -} - -/* - * Function: - * SendFailure - * - * Paramters: - * w - widget to own the selection - * sel - selection to assert - * ident - identifier - * str - error message - * - * Description: - * Sends a failure message - */ -static void -SendFailure(Widget w, Atom sel, ResIdent ident, char *str) -{ - _XEditResResetStream(&globals.stream); - _XEditResPutString8(&globals.stream, str); - SendCommand(w, sel, ident, Failure, &globals.stream); -} - -/* - * Function: - * BuildReturnPacket - * - * Parameters: - * ident - identifier - * command - command code - * stream - protocol stream - * Description: - * Builds a return packet, given the data to send - * - * Returns: - * packet to send - */ -static XtPointer -BuildReturnPacket(ResIdent ident, EditResError error, 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)error); - _XEditResPut32(stream, old_size); - - stream->alloc = old_alloc; - stream->current = old_current; - stream->size = old_size; - - return ((XtPointer)stream->real_top); -} - -/* - * Function: - * SendCommand - * Parameters: - * w - widget to own the selection - * sel - selection to assert - * ident - identifier - * command - command code - * stream - protocol stream - * - * Description: - * Builds a return command line - */ -static void -SendCommand(Widget w, Atom sel, ResIdent ident, EditResError error, - ProtocolStream *stream) -{ - BuildReturnPacket(ident, error, 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 - ************************************************************/ -static int -qcmp_widget_list(register _Xconst void *left, register _Xconst void *right) -{ - return (char *)*(Widget **)left - (char *)*(Widget **)right; -} - -/* - * Function: - * FindChildren - * - * Parameters: - * parent - parent widget - * children - list of children - * normal - return normal children - * popup - return popup children - * extra - return extra children - * - * Description: - * Retuns all children (popup, normal and otherwise) of this widget - * - * Returns: - * number of children - */ -static int -FindChildren(Widget parent, Widget **children, Bool normal, Bool popup, - Bool extra) -{ - CompositeWidget cw = (CompositeWidget)parent; - Cardinal i, num_children, current = 0; - Widget *extra_widgets = NULL; - Cardinal num_extra = 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 (XtIsWidget(parent) && extra) - { - XtResourceList norm_list, cons_list; - Cardinal num_norm, num_cons; - Arg args[1]; - Widget widget; - - XtGetResourceList(XtClass(parent), &norm_list, &num_norm); - - if (XtParent(parent) != NULL) - XtGetConstraintResourceList(XtClass(XtParent(parent)), - &cons_list, &num_cons); - else - num_cons = 0; - - extra_widgets = (Widget *)XtMalloc(sizeof(Widget)); - for (i = 0; i < num_norm; i++) - if (strcmp(norm_list[i].resource_type, XtRWidget) == 0) - { - widget = NULL; - XtSetArg(args[0], norm_list[i].resource_name, &widget); - XtGetValues(parent, args, 1); - if (widget && XtParent(widget) == parent) - { - ++num_extra; - extra_widgets = (Widget *) - XtRealloc((char *)extra_widgets, num_extra * sizeof(Widget)); - extra_widgets[num_extra - 1] = widget; - } - } - for (i = 0; i < num_cons; i++) - if (strcmp(cons_list[i].resource_type, XtRWidget) == 0) - { - widget = NULL; - XtSetArg(args[0], cons_list[i].resource_name, &widget); - XtGetValues(parent, args, 1); - if (widget && XtParent(widget) == parent) - { - ++num_extra; - extra_widgets = (Widget *) - XtRealloc((char *)extra_widgets, num_extra * sizeof(Widget)); - extra_widgets[num_extra - 1] = widget; - } - } - if (num_norm) - XtFree((char *)norm_list); - if (num_cons) - XtFree((char *)cons_list); - } - - if ((num_children + num_extra) == 0) - { - *children = NULL; - return (0); - } - - *children = (Widget *)XtMalloc(sizeof(Widget) * (num_children + num_extra)); - - 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]; - - if (num_extra) - /* Check for dups */ - { - Cardinal j, old_num_extra = num_extra; - - qsort(extra_widgets, num_extra, sizeof(Widget), qcmp_widget_list); - for (i = 0; i < num_extra - 1; i++) - while (i < num_extra - 1 && extra_widgets[i] == extra_widgets[i + 1]) - { - memmove(&extra_widgets[i], &extra_widgets[i + 1], - (num_extra - i) * sizeof(Widget)); - --num_extra; - } - - for (i = 0; i < num_children; i++) - for (j = 0; j < num_extra; j++) - if ((*children)[i] == extra_widgets[j]) - { - if ((j + 1) < num_extra) - memmove(&extra_widgets[j], &extra_widgets[j + 1], - (num_extra - j) * sizeof(Widget)); - --num_extra; - } - - if (old_num_extra != num_extra) - *children = (Widget *)XtRealloc((char *)*children, sizeof(Widget) - * (num_children + num_extra)); - - if (num_extra) - memcpy(&(*children)[num_children], extra_widgets, - sizeof(Widget) * num_extra); - } - if (extra_widgets) - XtFree((char *)extra_widgets); - if (num_children + num_extra == 0) - { - XtFree((char *)*children); - *children = NULL; - } - - return (num_children + num_extra); -} - -/* - * Function: - * IsChild - * - * parameters: - * top - top of the tree - * parent - parent widget - * child - child widget - * - * Description: - * Check to see of child is a child of parent - */ -static Bool -IsChild(Widget top, Widget parent, Widget child) -{ - int i, num_children; - Widget *children; - - if (parent == NULL) - return (top == child); - - num_children = FindChildren(parent, &children, True, True, True); - - for (i = 0; i < num_children; i++) - if (children[i] == child) - { - XtFree((char *)children); - return (True); - } - - XtFree((char *)children); - return (False); -} - -/* - * Function: - * VerifyWidget - * - * Parameters: - * w - any widget in the tree - * info - info about the widget to verify - * - * Description: - * Makes sure all the widgets still exist - */ -static char * -VerifyWidget(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 ("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: - * DoSetValues - * - * Parameters: - * w - a widget in the tree - * event - event that caused this action - * stream - protocol stream to add - * - * Description: - * Performs the setvalues requested - * - * Returns: - * NULL - */ -static char * -DoSetValues(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); - 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: - * HandleToolkitErrors - * - * Parameters: - * name - name of the error - * type - type of the error - * class - class of the error - * msg - the default message - * params - the extra parameters for this message - * num_params - "" - * - * Description: Handles X Toolkit Errors. - */ -/* ARGSUSED */ -static void -HandleToolkitErrors(String name, String type, String class, String msg, - String *params, Cardinal *num_params) -{ - SVErrorInfo *info = &globals.error_info; - char buf[BUFSIZ]; - - if (streq(name, "unknownType")) - XmuSnprintf(buf, sizeof(buf), - "The `%s' resource is not used by this widget.", - info->event->name); - else if (streq(name, "noColormap")) - XmuSnprintf(buf, sizeof(buf), msg, params[0]); - else if (streq(name, "conversionFailed") || streq(name, "conversionError")) - { - if (streq((String)info->event->value, XtRString)) - XmuSnprintf(buf, sizeof(buf), - "Could not convert the string '%s' for the `%s' " - "resource.", (String)info->event->value, - info->event->name); - else - XmuSnprintf(buf, sizeof(buf), - "Could not convert the `%s' resource.", - info->event->name); - } - else - XmuSnprintf(buf, sizeof(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: - * ExecuteSetValues - * - * Parameters: - * w - widget to perform the set_values on - * sv_event - set values event - * sv_info - set_value info - *. - * Description: - * Performs a setvalues for a given command - */ -static void -ExecuteSetValues(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 */ - 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: - * DumpWidgets - * - * Parameters: - * w - a widget in the tree - * event - event that caused this action - * stream - protocol stream to add - * - * Description: - * Given a widget it builds a protocol packet containing the entire - * widget heirarchy. - * - * Returns: - * NULL - */ -#define TOOLKIT_TYPE ("Xt") -/*ARGSUSED*/ -static char * -DumpWidgets(Widget w, EditresEvent *event, 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); - - /* - * write out toolkit type - */ - _XEditResPutString8(stream, TOOLKIT_TYPE); - - /* - * Overwrite the first 2 bytes with the real count - */ - *(stream->top) = count >> XER_NBBY; - *(stream->top + 1) = count; - - return (NULL); -} - -/* - * Function: - * DumpChildren - * - * Parameters: - * w - widget to dump - * stream - stream to dump to - * count - number of dumps we have performed - * - * Description: - * Adds a child's name to the list. - */ -/* 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(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") == 0) - return (True); - - return (False); -} - -static void -DumpChildren(Widget w, ProtocolStream *stream, unsigned short *count) -{ - int i, num_children; - Widget *children; - unsigned long window; - char *c_class; - - (*count)++; - - InsertWidget(stream, w); /* Insert the widget into the stream */ - - _XEditResPutString8(stream, XtName(w)); /* Insert name */ - - if (isApplicationShell(w)) - c_class = ((ApplicationShellWidget)w)->application.class; - else - c_class = XtClass(w)->core_class.class_name; - - _XEditResPutString8(stream, c_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, True); - for (i = 0; i < num_children; i++) - DumpChildren(children[i], stream, count); - - XtFree((char *)children); -} - -/************************************************************ - * Code for getting the geometry of widgets - ************************************************************/ -/* - * Function: - * DoGetGeometry - * - * Parameters: - * w - widget in the tree - * event - event that caused this action - * stream - protocol stream to add - * - * Description: - * Retrieves the Geometry of each specified widget. - * - * Returns: - * NULL - */ -static char * -DoGetGeometry(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 */ - } - else - ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream); - } - - return (NULL); -} - -/* - * Function: - * ExecuteGetGeometry - * - * Parameters: - * w - widget to get geometry - * stream - stream to append to - * - * Description: - * Gets the geometry for each widget specified. - * - * Returns: - * True if no error occured. - */ -static void -ExecuteGetGeometry(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: - * PositionInChild - * - * Parameters: - * child - child widget to check - * x - location of point to check in the parent's coord space - * y - "" - * - * Description: - * Returns true if this location is in the child. - */ -static Bool -PositionInChild(Widget child, int x, int 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) - && 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: - * _FindChild - * - * Parameters: - * parent - widget that is known to contain the point specified - * x - point in coordinates relative to the widget specified - * y - "" - * - * Description: - * Finds the child that actually contains the point shown. - */ -static Widget -_FindChild(Widget parent, int x, int y) -{ - Widget *children; - int i = FindChildren(parent, &children, True, False, True); - - 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: - * DoFindChild - * - * Parameters: - * w - widget in the tree - * event - event that caused this action - * stream - protocol stream to add - * Description: - * Finds the child that contains the location specified. - * - * Returns: - * An allocated error message if something went horribly wrong and - * no set values were performed, else NULL. - */ -static char * -DoFindChild(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: - * DoGetResources - * - * Parameters: - * w - widget in the tree - * event - event that caused this action - * stream - protocol stream to add - * - * Description: - * Gets the Resources associated with the widgets passed. - * - * Returns: - * NULL - */ -static char * -DoGetResources(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 */ - } - else - { - _XEditResPutBool(stream, False); /* no error occured */ - ExecuteGetResources(res_event->widgets[i].real_widget, stream); - } - } - - return (NULL); -} - -/* Function: - * ExecuteGetResources - * - * Parameters: - * w - widget to get resources on - * stream - protocol stream - * - * Description: - * Gets the resources for any individual widget - */ -static void -ExecuteGetResources(Widget w, ProtocolStream *stream) -{ - XtResourceList norm_list, cons_list; - Cardinal num_norm, num_cons; - register Cardinal 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 < 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 < 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); - } -} - -/* - * Function: - * DumpValues - * - * Parameters: - * event - event that caused this action - * stream - protocol stream to add - * - * Description: - * Returns resource values to the resource editor. - * - * Returns: - * NULL - */ -/*ARGSUSED*/ -static char * -DumpValues(Widget w, EditresEvent* event, ProtocolStream* stream) -{ - char *str; - Arg warg[1]; - String res_value = NULL; - GetValuesEvent *gv_event = (GetValuesEvent *)event; - - /* put the count in the stream */ - _XEditResPut16(stream, (unsigned int)1); - - /* - * Get the resource of the widget asked for by the - * resource editor and insert it into the stream - */ - XtSetArg(warg[0], gv_event->name, &res_value); - - if ((str = VerifyWidget(w, &gv_event->widgets[0])) != NULL) - _XEditResPutString8(stream, str); - else - { - _XEditresGetStringValues(gv_event->widgets[0].real_widget, warg, 1); - if (!res_value) - res_value = "NoValue"; - _XEditResPutString8(stream, res_value); - } - - return (NULL); -} - -/************************************************************ - * Code for inserting values into the protocol stream - ************************************************************/ -/* - * Function: - * InsertWidget - * - * Parameters: - * stream - protocol stream - * w - widget to insert - * - * Description: - * Inserts the full parent hierarchy of this widget into the protocol - * stream as a widget list. - */ -static void -InsertWidget(ProtocolStream *stream, Widget w) -{ - Widget temp; - unsigned long *widget_list; - register int i, num_widgets; - - for (temp = w, i = 0; temp != NULL; 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: - * _XEditResPutString8 - * - * Parameters: - * stream - stream to insert string into - * str - string to insert - * - * Description: - * Inserts a string into the protocol stream. - */ -void -_XEditResPutString8(ProtocolStream *stream, char *str) -{ - int i, len = strlen(str); - - _XEditResPut16(stream, len); - for (i = 0; i < len; i++, str++) - _XEditResPut8(stream, *str); -} - -/* - * Function: - * _XEditResPut8 - * - * Parameters: - * stream - stream to insert string into - * value - value to insert - * - * Description: - * Inserts an 8 bit integer into the protocol stream. - */ -void -_XEditResPut8(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: - * _XEditResPut16 - * - * Arguments: - * stream - stream to insert string into - * value - value to insert - * - * Description: - * Inserts a 16 bit integer into the protocol stream. - */ -void -_XEditResPut16(ProtocolStream *stream, unsigned int value) -{ - _XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK); - _XEditResPut8(stream, value & BYTE_MASK); -} - -/* - * Function: - * _XEditResPut32 - * - * Arguments: - * stream - stream to insert string into - * value - value to insert - * - * Description: - * Inserts a 32 bit integer into the protocol stream. - */ -void -_XEditResPut32(ProtocolStream *stream, unsigned long value) -{ - int i; - - for (i = 3; i >= 0; i--) - _XEditResPut8(stream, (value >> (XER_NBBY * i)) & BYTE_MASK); -} - -/* - * Function: - * _XEditResPutWidgetInfo - * - * Parameters: - * stream - stream to insert widget info into - * info - info to insert - * - * Description: - * Inserts the widget info into the protocol stream. - */ -void -_XEditResPutWidgetInfo(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: - * _XEditResResetStream - * - * Parameters: - * stream - stream to reset - * - * Description: - * Resets the protocol stream. - */ -void -_XEditResResetStream(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: - * _XEditResGetg8 - * - * Parameters: - * stream - protocol stream - * value - a pointer to value to return - * - * Description: - * Retrieves an unsigned 8 bit value from the protocol stream. - * - * Returns: - * True if sucessful - */ -Bool -_XEditResGet8(ProtocolStream *stream, unsigned char *value) -{ - if (stream->size < (unsigned long)(stream->current - stream->top)) - return (False); - - *value = *((stream->current)++); - return (True); -} - -/* - * Function: - * _XEditResGet16 - * - * Parameters: - * stream - protocol stream - * value - pointer to return value - * - * Description: - * Retrieves an unsigned 16 bit value from the protocol stream. - * - * Returns: - * True if sucessful - */ -Bool -_XEditResGet16(ProtocolStream *stream, unsigned short *value) -{ - unsigned char temp1, temp2; - - if (!(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2))) - return (False); - - *value = ((unsigned short)temp1 << XER_NBBY) + (unsigned short)temp2; - return (True); -} - -/* - * Function: - * _XEditResGetSigned16 - * - * Parameters: - * stream - protocol stream - * value - pointer to return value - * - * Description: - * Retrieves an signed 16 bit value from the protocol stream. - * - * Returns: - * True if sucessful - */ -Bool -_XEditResGetSigned16(ProtocolStream *stream, short *value) -{ - 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 */ - { - *value = -1; /* store all 1's */ - *value &= (temp1 << XER_NBBY); /* Now and in the MSB */ - *value &= temp2; /* and LSB */ - } - else - *value = ((unsigned short)temp1 << XER_NBBY) + (unsigned short)temp2; - - return (True); -} - -/* - * Function: - * _XEditResGet32 - * - * Parameters: - * stream - protocol stream - * value - pointer to return value - * - * Description: - * Retrieves an unsigned 32 bit value from the protocol stream. - * - * Returns: - * True if sucessful - */ -Bool -_XEditResGet32(ProtocolStream *stream, unsigned long *value) -{ - unsigned short temp1, temp2; - - if (!(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2))) - return (False); - - *value = ((unsigned short)temp1 << (XER_NBBY * 2)) + (unsigned short)temp2; - return (True); -} - -/* Function: - * _XEditResGetString8 - * - * Parameters: - * stream - protocol stream - * str - string to retrieve - * - * Description: - * Retrieves an 8 bit string value from the protocol stream. - * - * Returns: - * True if retrieval was successful - */ -Bool -_XEditResGetString8(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'; - - return (True); -} - -/* - * Function: - * _XEditResGetWidgetInfo - * - * Parameters: - * stream - protocol stream - * info - widget info struct to store into - * - * Description: - * Retrieves the list of widgets that follow and stores them in the - * widget info structure provided. - * - * Returns: - * True if retrieval was successful - */ -Bool -_XEditResGetWidgetInfo(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); - } -#if defined(LONG64) || defined(WORD64) - info->ids[i] |= globals.base_address; -#endif - } - return (True); -} - -/************************************************************ - * Code for Loading the EditresBlock resource - ************************************************************/ -/* - * Function: - * CvStringToBlock - * - * Parameters: - * dpy - display - * args - unused - * num_args - unused - * from_val - value to convert - * to_val - where to store - * converter_data - unused - * - * Description: - * Converts a string to an editres block value. - * - * Returns: - * True if conversion was sucessful - */ -/*ARGSUSED*/ -static Boolean -CvtStringToBlock(Display *dpy, XrmValue *args, Cardinal *num_args, - XrmValue *from_val, XrmValue *to_val, - XtPointer *converter_data) -{ - char ptr[16]; - static EditresBlock block; - - XmuNCopyISOLatin1Lowered(ptr, from_val->addr, sizeof(ptr)); - - 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: - * LoadResources - * - * Parameters: - * w - any widget in the tree - * - * Description: - * Loads a global resource the determines of this application should - * allow Editres requests. - */ -static void -LoadResources(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, 0, XtCacheAll, NULL); - - XtGetApplicationResources(w, (XtPointer)&globals, resources, - XtNumber(resources), NULL, 0); -} - -/* - * Function: - * _XEditresGetStringValues - * - * Parameters: - * w - widget - * warg - where to store result - * numargs - unused - */ -/*ARGSUSED*/ -static void -_XEditresGetStringValues(Widget w, Arg *warg, int numargs) -{ - static char buffer[32]; - XtResourceList res_list; - Cardinal num_res; - XtResource *res = NULL; - long value; - Cardinal i; - char *string = ""; - Arg args[1]; - XrmValue to, from; - - /* - * Look for the resource - */ - XtGetResourceList(XtClass(w), &res_list, &num_res); - for (i = 0; i < num_res; i++) - if (strcmp(res_list[i].resource_name, warg->name) == 0) - { - res = &res_list[i]; - break; - } - - if (res == NULL && XtParent(w) != NULL) - { - XtFree((char *)res_list); - XtGetConstraintResourceList(XtClass(XtParent(w)), &res_list, &num_res); - for (i = 0; i < num_res; i++) - if (strcmp(res_list[i].resource_name, warg->name) == 0) - { - res = &res_list[i]; - break; - } - } - - if (res == NULL) - { - /* Couldn't find resource */ - - XtFree((char *)res_list); - *(XtPointer *)warg->value = NULL; - return; - } - - /* try to get the value in the proper size */ - switch (res->resource_size) - { -#ifdef LONG64 - long v8; -#endif - int v4; - short v2; - char v1; - - case 1: - XtSetArg(args[0], res->resource_name, &v1); - XtGetValues(w, args, 1); - value = (int)v1; - break; - case 2: - XtSetArg(args[0], res->resource_name, &v2); - XtGetValues(w, args, 1); - value = (int)v2; - break; - case 4: - XtSetArg(args[0], res->resource_name, &v4); - XtGetValues(w, args, 1); - value = (int)v4; - break; -#ifdef LONG64 - case 8: - XtSetArg(args[0], res->resource_name, &v8); - XtGetValues(w, args, 1); - value = (long)v8; - break; -#endif - default: - fprintf(stderr, "_XEditresGetStringValues: bad size %d\n", - res->resource_size); - string = "bad size"; - *(char **)(warg->value) = string; - XtFree((char *)res_list); - return; - } - - /* - * If the resource is already String, no conversion needed - */ - if (strcmp(XtRString, res->resource_type) == 0) - { - if (value == 0) - string = "(null)"; - else - string = (char *)value; - } - else - { - from.size = res->resource_size; - from.addr = (XPointer)&value; - to.addr = NULL; - to.size = 0; - - if (XtConvertAndStore(w,res->resource_type, &from, XtRString, &to)) - string = to.addr; - else - { - string = buffer; - /* - * Conversion failed, fall back to representing it as integer - */ - switch (res->resource_size) - { - case sizeof(char): - XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xff)); - break; - case sizeof(short): - XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xffff)); - break; - case sizeof(int): - XmuSnprintf(buffer, sizeof(buffer), "0x%08x", (int)value); - break; -#ifdef LONG64 - case sizeof(long): - XmuSnprintf(buffer, sizeof(buffer), "0x%016lx", value); - break; -#endif - } - } - } - - if (string == NULL) - string = ""; - - *(char **)(warg->value) = string; - XtFree((char *)res_list); -} +/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Chris D. Peterson, Dave Sternlicht, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/IntrinsicP.h> /* To get into the composite and core widget
+ structures. */
+#include <X11/ObjectP.h> /* For XtIs<Classname> macros. */
+#include <X11/StringDefs.h> /* for XtRString. */
+#include <X11/ShellP.h> /* for Application Shell Widget class. */
+
+#include <X11/Xatom.h>
+#include <X11/Xos.h> /* for strcpy declaration */
+#include <X11/Xfuncs.h>
+#include <X11/Xmu/EditresP.h>
+#include <X11/Xmd.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/SysUtil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define _XEditResPutBool _XEditResPut8
+#define _XEditResPutResourceType _XEditResPut8
+
+/*
+ * Types
+ */
+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 _GetValuesEvent {
+ EditresCommand type; /* first field must be type */
+ WidgetInfo *widgets;
+ unsigned short num_entries; /* number of get values requests */
+ char *name;
+} GetValuesEvent;
+
+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;
+
+/*
+ * 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 */
+#if defined(LONG64) || defined(WORD64)
+ unsigned long base_address;
+#endif
+} Globals;
+
+#define CURRENT_PROTOCOL_VERSION 5L
+
+#define streq(a,b) (strcmp((a), (b)) == 0)
+
+/*
+ * Prototypes
+ */
+static Widget _FindChild(Widget, int, int);
+static void _XEditresGetStringValues(Widget, Arg*, int);
+static XtPointer BuildReturnPacket(ResIdent, EditResError, ProtocolStream*);
+static void CommandDone(Widget, Atom*, Atom*);
+static Boolean ConvertReturnCommand(Widget, Atom*, Atom*, Atom*, XtPointer*,
+ unsigned long*, int*);
+static Boolean CvtStringToBlock(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static EditresEvent *BuildEvent(Widget, Atom, XtPointer, ResIdent,
+ unsigned long);
+static char *DoFindChild(Widget, EditresEvent*, ProtocolStream*);
+static char *DoGetGeometry(Widget, EditresEvent*, ProtocolStream*);
+static char *DoGetResources(Widget, EditresEvent*, ProtocolStream*);
+static char *DoSetValues(Widget, EditresEvent*, ProtocolStream*);
+static void DumpChildren(Widget, ProtocolStream*, unsigned short*);
+static char *DumpValues(Widget, EditresEvent*, ProtocolStream*);
+static char *DumpWidgets(Widget, EditresEvent*, ProtocolStream*);
+static void ExecuteCommand(Widget, Atom, ResIdent, EditresEvent*);
+static void ExecuteGetGeometry(Widget, ProtocolStream*);
+static void ExecuteGetResources(Widget w, ProtocolStream *stream);
+static void ExecuteSetValues(Widget, SetValuesEvent*, WidgetInfo*,
+ ProtocolStream*, unsigned short*);
+static void FreeEvent(EditresEvent*);
+static void GetCommand(Widget w, XtPointer, Atom*, Atom*, XtPointer,
+ unsigned long*, int*);
+static void HandleToolkitErrors(String, String, String, String,
+ String*, Cardinal*);
+static void InsertWidget(ProtocolStream*, Widget);
+static Bool IsChild(Widget, Widget, Widget);
+static Bool isApplicationShell(Widget);
+static void LoadResources(Widget);
+static Bool PositionInChild(Widget, int, int);
+static int qcmp_widget_list(register _Xconst void*, register _Xconst void*);
+static void SendCommand(Widget, Atom, ResIdent, EditResError,
+ ProtocolStream*);
+static void SendFailure(Widget, Atom, ResIdent, char*);
+static char *VerifyWidget(Widget, WidgetInfo*);
+
+/*
+ * External
+ */
+void _XEditResCheckMessages(Widget, XtPointer, XEvent*, Boolean*);
+
+/*
+ * Initialization
+ */
+static Atom res_editor_command, res_editor_protocol, client_value;
+static Globals globals;
+
+/************************************************************
+ * Resource Editor Communication Code
+ ************************************************************/
+/*
+ * Function:
+ * _XEditResCheckMessages
+ *
+ * Parameters:
+ * data - unused
+ * event - The X Event that triggered this handler
+ * cont - unused
+ *
+ * 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.
+ */
+/*ARGSUSED*/
+void
+_XEditResCheckMessages(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)
+ {
+ Atom atoms[4];
+ static char *names[] = {
+ EDITRES_NAME, EDITRES_COMMAND_ATOM,
+ EDITRES_PROTOCOL_ATOM, EDITRES_CLIENT_VALUE
+ };
+
+ first_time = True;
+ XInternAtoms(dpy, names, 4, False, atoms);
+ res_editor = atoms[0];
+ res_editor_command = atoms[1];
+ res_editor_protocol = atoms[2];
+ /* Used in later procedures */
+ client_value = atoms[3];
+ 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,
+ (unsigned int) 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:
+ * BuildEvent
+ *
+ * Parameters:
+ * 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
+ *
+ * Description:
+ * Takes the info out the protocol stream an constructs
+ * the proper event structure.
+ *
+ * Returns:
+ * the event, or NULL
+ */
+#if defined(ERROR_MESSAGE)
+#undef ERROR_MESSAGE
+#endif
+#define ERROR_MESSAGE "Client: Improperly formatted protocol request"
+static EditresEvent *
+BuildEvent(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;
+ 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, 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';
+
+ 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;
+ case GetValues:
+ {
+ GetValuesEvent *gv_event = (GetValuesEvent *)event;
+
+ _XEditResGetString8(stream, &gv_event->name);
+ _XEditResGet16(stream, &gv_event->num_entries);
+ gv_event->widgets = (WidgetInfo *)
+ XtCalloc(sizeof(WidgetInfo), gv_event->num_entries);
+ _XEditResGetWidgetInfo(stream, gv_event->widgets);
+ }
+ break;
+ default:
+ {
+ char buf[BUFSIZ];
+
+ XmuSnprintf(buf, sizeof(buf),
+ "Unknown Protocol request %d.", event->any_event.type);
+ SendFailure(w, sel, ident, buf);
+ FreeEvent(event);
+ return (NULL);
+ }
+ }
+
+ return (event);
+
+ done:
+ SendFailure(w, sel, ident, ERROR_MESSAGE);
+ FreeEvent(event);
+ return (NULL);
+}
+
+/*
+ * Function:
+ * FreeEvent
+ *
+ * Parameters:
+ * event - event to free
+ *
+ * Description:
+ * Frees the event structure and any other pieces in it that need freeing.
+ */
+static void
+FreeEvent(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(event->set_values_event.res_type);
+ }
+
+ XtFree((char *)event);
+}
+
+/*
+ * Function:
+ * GetCommand
+ *
+ * Parameters:
+ * (See Xt XtConvertSelectionProc)
+ * data - contains the ident number for the command
+ *
+ * Description:
+ * Gets the Command out of the selection asserted by the resource manager.
+ */
+/*ARGSUSED*/
+static void
+GetCommand(Widget w, XtPointer data, Atom *selection, Atom *type,
+ XtPointer value, 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:
+ * ExecuteCommand
+ *
+ * Parameters:
+ * w - widget
+ * command - the command to execute
+ * value - the associated with the command
+ *
+ * Description:
+ * Executes a command string received from the resource editor.
+ */
+/*ARGSUSED*/
+static void
+ExecuteCommand(Widget w, Atom sel, ResIdent ident, EditresEvent *event)
+{
+ char *(*func)(Widget, EditresEvent*, ProtocolStream*);
+ 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:
+#if defined(LONG64) || defined(WORD64)
+ globals.base_address = (unsigned long)w & 0xFFFFFFFF00000000;
+#endif
+ func = DumpWidgets;
+ break;
+ case SetValues:
+ func = DoSetValues;
+ break;
+ case FindChild:
+ func = DoFindChild;
+ break;
+ case GetGeometry:
+ func = DoGetGeometry;
+ break;
+ case GetResources:
+ func = DoGetResources;
+ break;
+ case GetValues:
+ func = DumpValues;
+ break;
+ default:
+ {
+ char buf[BUFSIZ];
+
+ XmuSnprintf(buf, sizeof(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);
+}
+
+/*
+ * Function:
+ * ConvertReturnCommand
+ *
+ * Parameters:
+ * 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
+ *
+ * Description:
+ * Converts a selection
+ *
+ * Returns:
+ * True if conversion was sucessful
+ */
+/*ARGSUSED*/
+static Boolean
+ConvertReturnCommand(Widget w, Atom *selection, Atom *target, Atom *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:
+ * CommandDone
+ *
+ * Parameters:
+ * widget - unused
+ * selection - unused
+ * target - unused
+ *
+ * Description:
+ * done with the selection
+ */
+/*ARGSUSED*/
+static void
+CommandDone(Widget widget, Atom *selection, Atom *target)
+{
+ /* Keep the toolkit from automaticaly freeing the selection value */
+}
+
+/*
+ * Function:
+ * SendFailure
+ *
+ * Paramters:
+ * w - widget to own the selection
+ * sel - selection to assert
+ * ident - identifier
+ * str - error message
+ *
+ * Description:
+ * Sends a failure message
+ */
+static void
+SendFailure(Widget w, Atom sel, ResIdent ident, char *str)
+{
+ _XEditResResetStream(&globals.stream);
+ _XEditResPutString8(&globals.stream, str);
+ SendCommand(w, sel, ident, Failure, &globals.stream);
+}
+
+/*
+ * Function:
+ * BuildReturnPacket
+ *
+ * Parameters:
+ * ident - identifier
+ * command - command code
+ * stream - protocol stream
+ * Description:
+ * Builds a return packet, given the data to send
+ *
+ * Returns:
+ * packet to send
+ */
+static XtPointer
+BuildReturnPacket(ResIdent ident, EditResError error, 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)error);
+ _XEditResPut32(stream, old_size);
+
+ stream->alloc = old_alloc;
+ stream->current = old_current;
+ stream->size = old_size;
+
+ return ((XtPointer)stream->real_top);
+}
+
+/*
+ * Function:
+ * SendCommand
+ * Parameters:
+ * w - widget to own the selection
+ * sel - selection to assert
+ * ident - identifier
+ * command - command code
+ * stream - protocol stream
+ *
+ * Description:
+ * Builds a return command line
+ */
+static void
+SendCommand(Widget w, Atom sel, ResIdent ident, EditResError error,
+ ProtocolStream *stream)
+{
+ BuildReturnPacket(ident, error, 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
+ ************************************************************/
+static int
+qcmp_widget_list(register _Xconst void *left, register _Xconst void *right)
+{
+ return (char *)*(Widget **)left - (char *)*(Widget **)right;
+}
+
+/*
+ * Function:
+ * FindChildren
+ *
+ * Parameters:
+ * parent - parent widget
+ * children - list of children
+ * normal - return normal children
+ * popup - return popup children
+ * extra - return extra children
+ *
+ * Description:
+ * Retuns all children (popup, normal and otherwise) of this widget
+ *
+ * Returns:
+ * number of children
+ */
+static int
+FindChildren(Widget parent, Widget **children, Bool normal, Bool popup,
+ Bool extra)
+{
+ CompositeWidget cw = (CompositeWidget)parent;
+ Cardinal i, num_children, current = 0;
+ Widget *extra_widgets = NULL;
+ Cardinal num_extra = 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 (XtIsWidget(parent) && extra)
+ {
+ XtResourceList norm_list, cons_list;
+ Cardinal num_norm, num_cons;
+ Arg args[1];
+ Widget widget;
+
+ XtGetResourceList(XtClass(parent), &norm_list, &num_norm);
+
+ if (XtParent(parent) != NULL)
+ XtGetConstraintResourceList(XtClass(XtParent(parent)),
+ &cons_list, &num_cons);
+ else
+ num_cons = 0;
+
+ extra_widgets = (Widget *)XtMalloc(sizeof(Widget));
+ for (i = 0; i < num_norm; i++)
+ if (strcmp(norm_list[i].resource_type, XtRWidget) == 0)
+ {
+ widget = NULL;
+ XtSetArg(args[0], norm_list[i].resource_name, &widget);
+ XtGetValues(parent, args, 1);
+ if (widget && XtParent(widget) == parent)
+ {
+ ++num_extra;
+ extra_widgets = (Widget *) XtRealloc(
+ (char *)extra_widgets, num_extra * sizeof(Widget));
+ extra_widgets[num_extra - 1] = widget;
+ }
+ }
+ for (i = 0; i < num_cons; i++)
+ if (strcmp(cons_list[i].resource_type, XtRWidget) == 0)
+ {
+ widget = NULL;
+ XtSetArg(args[0], cons_list[i].resource_name, &widget);
+ XtGetValues(parent, args, 1);
+ if (widget && XtParent(widget) == parent)
+ {
+ ++num_extra;
+ extra_widgets = (Widget *) XtRealloc(
+ (char *)extra_widgets, num_extra * sizeof(Widget));
+ extra_widgets[num_extra - 1] = widget;
+ }
+ }
+ if (num_norm)
+ XtFree((char *)norm_list);
+ if (num_cons)
+ XtFree((char *)cons_list);
+ }
+
+ if ((num_children + num_extra) == 0)
+ {
+ *children = NULL;
+ return (0);
+ }
+
+ *children = (Widget *)XtMalloc(sizeof(Widget) * (num_children + num_extra));
+
+ 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];
+
+ if (num_extra)
+ /* Check for dups */
+ {
+ Cardinal j, old_num_extra = num_extra;
+
+ qsort(extra_widgets, num_extra, sizeof(Widget), qcmp_widget_list);
+ for (i = 0; i < num_extra - 1; i++)
+ while (i < num_extra - 1 &&
+ extra_widgets[i] == extra_widgets[i + 1])
+ {
+ memmove(&extra_widgets[i], &extra_widgets[i + 1],
+ (num_extra - i) * sizeof(Widget));
+ --num_extra;
+ }
+
+ for (i = 0; i < num_children; i++)
+ for (j = 0; j < num_extra; j++)
+ if ((*children)[i] == extra_widgets[j])
+ {
+ if ((j + 1) < num_extra)
+ memmove(&extra_widgets[j], &extra_widgets[j + 1],
+ (num_extra - j) * sizeof(Widget));
+ --num_extra;
+ }
+
+ if (old_num_extra != num_extra)
+ *children = (Widget *)XtRealloc((char *)*children, sizeof(Widget)
+ * (num_children + num_extra));
+
+ if (num_extra)
+ memcpy(&(*children)[num_children], extra_widgets,
+ sizeof(Widget) * num_extra);
+ }
+ if (extra_widgets)
+ XtFree((char *)extra_widgets);
+ if (num_children + num_extra == 0)
+ {
+ XtFree((char *)*children);
+ *children = NULL;
+ }
+
+ return (num_children + num_extra);
+}
+
+/*
+ * Function:
+ * IsChild
+ *
+ * parameters:
+ * top - top of the tree
+ * parent - parent widget
+ * child - child widget
+ *
+ * Description:
+ * Check to see of child is a child of parent
+ */
+static Bool
+IsChild(Widget top, Widget parent, Widget child)
+{
+ int i, num_children;
+ Widget *children;
+
+ if (parent == NULL)
+ return (top == child);
+
+ num_children = FindChildren(parent, &children, True, True, True);
+
+ for (i = 0; i < num_children; i++)
+ if (children[i] == child)
+ {
+ XtFree((char *)children);
+ return (True);
+ }
+
+ XtFree((char *)children);
+ return (False);
+}
+
+/*
+ * Function:
+ * VerifyWidget
+ *
+ * Parameters:
+ * w - any widget in the tree
+ * info - info about the widget to verify
+ *
+ * Description:
+ * Makes sure all the widgets still exist
+ */
+static char *
+VerifyWidget(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 ("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:
+ * DoSetValues
+ *
+ * Parameters:
+ * w - a widget in the tree
+ * event - event that caused this action
+ * stream - protocol stream to add
+ *
+ * Description:
+ * Performs the setvalues requested
+ *
+ * Returns:
+ * NULL
+ */
+static char *
+DoSetValues(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);
+ 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:
+ * HandleToolkitErrors
+ *
+ * Parameters:
+ * name - name of the error
+ * type - type of the error
+ * class - class of the error
+ * msg - the default message
+ * params - the extra parameters for this message
+ * num_params - ""
+ *
+ * Description: Handles X Toolkit Errors.
+ */
+/* ARGSUSED */
+static void
+HandleToolkitErrors(String name, String type, String class, String msg,
+ String *params, Cardinal *num_params)
+{
+ SVErrorInfo *info = &globals.error_info;
+ char buf[BUFSIZ];
+
+ if (streq(name, "unknownType"))
+ XmuSnprintf(buf, sizeof(buf),
+ "The `%s' resource is not used by this widget.",
+ info->event->name);
+ else if (streq(name, "noColormap"))
+ XmuSnprintf(buf, sizeof(buf), msg, params[0]);
+ else if (streq(name, "conversionFailed") || streq(name, "conversionError"))
+ {
+ if (streq((String)info->event->value, XtRString))
+ XmuSnprintf(buf, sizeof(buf),
+ "Could not convert the string '%s' for the `%s' "
+ "resource.", (String)info->event->value,
+ info->event->name);
+ else
+ XmuSnprintf(buf, sizeof(buf),
+ "Could not convert the `%s' resource.",
+ info->event->name);
+ }
+ else
+ XmuSnprintf(buf, sizeof(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:
+ * ExecuteSetValues
+ *
+ * Parameters:
+ * w - widget to perform the set_values on
+ * sv_event - set values event
+ * sv_info - set_value info
+ *.
+ * Description:
+ * Performs a setvalues for a given command
+ */
+static void
+ExecuteSetValues(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 */
+ 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:
+ * DumpWidgets
+ *
+ * Parameters:
+ * w - a widget in the tree
+ * event - event that caused this action
+ * stream - protocol stream to add
+ *
+ * Description:
+ * Given a widget it builds a protocol packet containing the entire
+ * widget heirarchy.
+ *
+ * Returns:
+ * NULL
+ */
+#define TOOLKIT_TYPE ("Xt")
+/*ARGSUSED*/
+static char *
+DumpWidgets(Widget w, EditresEvent *event, 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);
+
+ /*
+ * write out toolkit type
+ */
+ _XEditResPutString8(stream, TOOLKIT_TYPE);
+
+ /*
+ * Overwrite the first 2 bytes with the real count
+ */
+ *(stream->top) = count >> XER_NBBY;
+ *(stream->top + 1) = count;
+
+ return (NULL);
+}
+
+/*
+ * Function:
+ * DumpChildren
+ *
+ * Parameters:
+ * w - widget to dump
+ * stream - stream to dump to
+ * count - number of dumps we have performed
+ *
+ * Description:
+ * Adds a child's name to the list.
+ */
+/* 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(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") == 0)
+ return (True);
+
+ return (False);
+}
+
+static void
+DumpChildren(Widget w, ProtocolStream *stream, unsigned short *count)
+{
+ int i, num_children;
+ Widget *children;
+ unsigned long window;
+ char *c_class;
+
+ (*count)++;
+
+ InsertWidget(stream, w); /* Insert the widget into the stream */
+
+ _XEditResPutString8(stream, XtName(w)); /* Insert name */
+
+ if (isApplicationShell(w))
+ c_class = ((ApplicationShellWidget)w)->application.class;
+ else
+ c_class = XtClass(w)->core_class.class_name;
+
+ _XEditResPutString8(stream, c_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, True);
+ for (i = 0; i < num_children; i++)
+ DumpChildren(children[i], stream, count);
+
+ XtFree((char *)children);
+}
+
+/************************************************************
+ * Code for getting the geometry of widgets
+ ************************************************************/
+/*
+ * Function:
+ * DoGetGeometry
+ *
+ * Parameters:
+ * w - widget in the tree
+ * event - event that caused this action
+ * stream - protocol stream to add
+ *
+ * Description:
+ * Retrieves the Geometry of each specified widget.
+ *
+ * Returns:
+ * NULL
+ */
+static char *
+DoGetGeometry(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 */
+ }
+ else
+ ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream);
+ }
+
+ return (NULL);
+}
+
+/*
+ * Function:
+ * ExecuteGetGeometry
+ *
+ * Parameters:
+ * w - widget to get geometry
+ * stream - stream to append to
+ *
+ * Description:
+ * Gets the geometry for each widget specified.
+ *
+ * Returns:
+ * True if no error occured.
+ */
+static void
+ExecuteGetGeometry(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:
+ * PositionInChild
+ *
+ * Parameters:
+ * child - child widget to check
+ * x - location of point to check in the parent's coord space
+ * y - ""
+ *
+ * Description:
+ * Returns true if this location is in the child.
+ */
+static Bool
+PositionInChild(Widget child, int x, int 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)
+ && 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:
+ * _FindChild
+ *
+ * Parameters:
+ * parent - widget that is known to contain the point specified
+ * x - point in coordinates relative to the widget specified
+ * y - ""
+ *
+ * Description:
+ * Finds the child that actually contains the point shown.
+ */
+static Widget
+_FindChild(Widget parent, int x, int y)
+{
+ Widget *children;
+ int i = FindChildren(parent, &children, True, False, True);
+
+ 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:
+ * DoFindChild
+ *
+ * Parameters:
+ * w - widget in the tree
+ * event - event that caused this action
+ * stream - protocol stream to add
+ * Description:
+ * Finds the child that contains the location specified.
+ *
+ * Returns:
+ * An allocated error message if something went horribly wrong and
+ * no set values were performed, else NULL.
+ */
+static char *
+DoFindChild(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:
+ * DoGetResources
+ *
+ * Parameters:
+ * w - widget in the tree
+ * event - event that caused this action
+ * stream - protocol stream to add
+ *
+ * Description:
+ * Gets the Resources associated with the widgets passed.
+ *
+ * Returns:
+ * NULL
+ */
+static char *
+DoGetResources(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 */
+ }
+ else
+ {
+ _XEditResPutBool(stream, False); /* no error occured */
+ ExecuteGetResources(res_event->widgets[i].real_widget, stream);
+ }
+ }
+
+ return (NULL);
+}
+
+/* Function:
+ * ExecuteGetResources
+ *
+ * Parameters:
+ * w - widget to get resources on
+ * stream - protocol stream
+ *
+ * Description:
+ * Gets the resources for any individual widget
+ */
+static void
+ExecuteGetResources(Widget w, ProtocolStream *stream)
+{
+ XtResourceList norm_list, cons_list;
+ Cardinal num_norm, num_cons;
+ register Cardinal 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 < 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 < 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);
+ }
+}
+
+/*
+ * Function:
+ * DumpValues
+ *
+ * Parameters:
+ * event - event that caused this action
+ * stream - protocol stream to add
+ *
+ * Description:
+ * Returns resource values to the resource editor.
+ *
+ * Returns:
+ * NULL
+ */
+/*ARGSUSED*/
+static char *
+DumpValues(Widget w, EditresEvent* event, ProtocolStream* stream)
+{
+ char *str;
+ Arg warg[1];
+ String res_value = NULL;
+ GetValuesEvent *gv_event = (GetValuesEvent *)event;
+
+ /* put the count in the stream */
+ _XEditResPut16(stream, (unsigned int)1);
+
+ /*
+ * Get the resource of the widget asked for by the
+ * resource editor and insert it into the stream
+ */
+ XtSetArg(warg[0], gv_event->name, &res_value);
+
+ if ((str = VerifyWidget(w, &gv_event->widgets[0])) != NULL)
+ _XEditResPutString8(stream, str);
+ else
+ {
+ _XEditresGetStringValues(gv_event->widgets[0].real_widget, warg, 1);
+ if (!res_value)
+ res_value = "NoValue";
+ _XEditResPutString8(stream, res_value);
+ }
+
+ return (NULL);
+}
+
+/************************************************************
+ * Code for inserting values into the protocol stream
+ ************************************************************/
+/*
+ * Function:
+ * InsertWidget
+ *
+ * Parameters:
+ * stream - protocol stream
+ * w - widget to insert
+ *
+ * Description:
+ * Inserts the full parent hierarchy of this widget into the protocol
+ * stream as a widget list.
+ */
+static void
+InsertWidget(ProtocolStream *stream, Widget w)
+{
+ Widget temp;
+ unsigned long *widget_list;
+ register int i, num_widgets;
+
+ for (temp = w, i = 0; temp != NULL; 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:
+ * _XEditResPutString8
+ *
+ * Parameters:
+ * stream - stream to insert string into
+ * str - string to insert
+ *
+ * Description:
+ * Inserts a string into the protocol stream.
+ */
+void
+_XEditResPutString8(ProtocolStream *stream, char *str)
+{
+ int i, len = strlen(str);
+
+ _XEditResPut16(stream, len);
+ for (i = 0; i < len; i++, str++)
+ _XEditResPut8(stream, *str);
+}
+
+/*
+ * Function:
+ * _XEditResPut8
+ *
+ * Parameters:
+ * stream - stream to insert string into
+ * value - value to insert
+ *
+ * Description:
+ * Inserts an 8 bit integer into the protocol stream.
+ */
+void
+_XEditResPut8(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:
+ * _XEditResPut16
+ *
+ * Arguments:
+ * stream - stream to insert string into
+ * value - value to insert
+ *
+ * Description:
+ * Inserts a 16 bit integer into the protocol stream.
+ */
+void
+_XEditResPut16(ProtocolStream *stream, unsigned int value)
+{
+ _XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK);
+ _XEditResPut8(stream, value & BYTE_MASK);
+}
+
+/*
+ * Function:
+ * _XEditResPut32
+ *
+ * Arguments:
+ * stream - stream to insert string into
+ * value - value to insert
+ *
+ * Description:
+ * Inserts a 32 bit integer into the protocol stream.
+ */
+void
+_XEditResPut32(ProtocolStream *stream, unsigned long value)
+{
+ int i;
+
+ for (i = 3; i >= 0; i--)
+ _XEditResPut8(stream, (value >> (XER_NBBY * i)) & BYTE_MASK);
+}
+
+/*
+ * Function:
+ * _XEditResPutWidgetInfo
+ *
+ * Parameters:
+ * stream - stream to insert widget info into
+ * info - info to insert
+ *
+ * Description:
+ * Inserts the widget info into the protocol stream.
+ */
+void
+_XEditResPutWidgetInfo(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:
+ * _XEditResResetStream
+ *
+ * Parameters:
+ * stream - stream to reset
+ *
+ * Description:
+ * Resets the protocol stream.
+ */
+void
+_XEditResResetStream(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:
+ * _XEditResGetg8
+ *
+ * Parameters:
+ * stream - protocol stream
+ * value - a pointer to value to return
+ *
+ * Description:
+ * Retrieves an unsigned 8 bit value from the protocol stream.
+ *
+ * Returns:
+ * True if sucessful
+ */
+Bool
+_XEditResGet8(ProtocolStream *stream, unsigned char *value)
+{
+ if (stream->size < (unsigned long)(stream->current - stream->top))
+ return (False);
+
+ *value = *((stream->current)++);
+ return (True);
+}
+
+/*
+ * Function:
+ * _XEditResGet16
+ *
+ * Parameters:
+ * stream - protocol stream
+ * value - pointer to return value
+ *
+ * Description:
+ * Retrieves an unsigned 16 bit value from the protocol stream.
+ *
+ * Returns:
+ * True if sucessful
+ */
+Bool
+_XEditResGet16(ProtocolStream *stream, unsigned short *value)
+{
+ unsigned char temp1, temp2;
+
+ if (!(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)))
+ return (False);
+
+ *value = ((unsigned short)temp1 << XER_NBBY) + (unsigned short)temp2;
+ return (True);
+}
+
+/*
+ * Function:
+ * _XEditResGetSigned16
+ *
+ * Parameters:
+ * stream - protocol stream
+ * value - pointer to return value
+ *
+ * Description:
+ * Retrieves an signed 16 bit value from the protocol stream.
+ *
+ * Returns:
+ * True if sucessful
+ */
+Bool
+_XEditResGetSigned16(ProtocolStream *stream, short *value)
+{
+ 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 */
+ {
+ *value = -1; /* store all 1's */
+ *value &= (temp1 << XER_NBBY); /* Now and in the MSB */
+ *value &= temp2; /* and LSB */
+ }
+ else
+ *value = ((unsigned short)temp1 << XER_NBBY) + (unsigned short)temp2;
+
+ return (True);
+}
+
+/*
+ * Function:
+ * _XEditResGet32
+ *
+ * Parameters:
+ * stream - protocol stream
+ * value - pointer to return value
+ *
+ * Description:
+ * Retrieves an unsigned 32 bit value from the protocol stream.
+ *
+ * Returns:
+ * True if sucessful
+ */
+Bool
+_XEditResGet32(ProtocolStream *stream, unsigned long *value)
+{
+ unsigned short temp1, temp2;
+
+ if (!(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2)))
+ return (False);
+
+ *value = ((unsigned short)temp1 << (XER_NBBY * 2)) + (unsigned short)temp2;
+ return (True);
+}
+
+/* Function:
+ * _XEditResGetString8
+ *
+ * Parameters:
+ * stream - protocol stream
+ * str - string to retrieve
+ *
+ * Description:
+ * Retrieves an 8 bit string value from the protocol stream.
+ *
+ * Returns:
+ * True if retrieval was successful
+ */
+Bool
+_XEditResGetString8(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';
+
+ return (True);
+}
+
+/*
+ * Function:
+ * _XEditResGetWidgetInfo
+ *
+ * Parameters:
+ * stream - protocol stream
+ * info - widget info struct to store into
+ *
+ * Description:
+ * Retrieves the list of widgets that follow and stores them in the
+ * widget info structure provided.
+ *
+ * Returns:
+ * True if retrieval was successful
+ */
+Bool
+_XEditResGetWidgetInfo(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);
+ }
+#if defined(LONG64) || defined(WORD64)
+ info->ids[i] |= globals.base_address;
+#endif
+ }
+ return (True);
+}
+
+/************************************************************
+ * Code for Loading the EditresBlock resource
+ ************************************************************/
+/*
+ * Function:
+ * CvStringToBlock
+ *
+ * Parameters:
+ * dpy - display
+ * args - unused
+ * num_args - unused
+ * from_val - value to convert
+ * to_val - where to store
+ * converter_data - unused
+ *
+ * Description:
+ * Converts a string to an editres block value.
+ *
+ * Returns:
+ * True if conversion was sucessful
+ */
+/*ARGSUSED*/
+static Boolean
+CvtStringToBlock(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *from_val, XrmValue *to_val,
+ XtPointer *converter_data)
+{
+ char ptr[16];
+ static EditresBlock block;
+
+ XmuNCopyISOLatin1Lowered(ptr, from_val->addr, sizeof(ptr));
+
+ 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:
+ * LoadResources
+ *
+ * Parameters:
+ * w - any widget in the tree
+ *
+ * Description:
+ * Loads a global resource the determines of this application should
+ * allow Editres requests.
+ */
+static void
+LoadResources(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, 0, XtCacheAll, NULL);
+
+ XtGetApplicationResources(w, (XtPointer)&globals, resources,
+ XtNumber(resources), NULL, 0);
+}
+
+/*
+ * Function:
+ * _XEditresGetStringValues
+ *
+ * Parameters:
+ * w - widget
+ * warg - where to store result
+ * numargs - unused
+ */
+/*ARGSUSED*/
+static void
+_XEditresGetStringValues(Widget w, Arg *warg, int numargs)
+{
+ static char buffer[32];
+ XtResourceList res_list;
+ Cardinal num_res;
+ XtResource *res = NULL;
+ long value;
+ Cardinal i;
+ char *string = "";
+ Arg args[1];
+ XrmValue to, from;
+
+ /*
+ * Look for the resource
+ */
+ XtGetResourceList(XtClass(w), &res_list, &num_res);
+ for (i = 0; i < num_res; i++)
+ if (strcmp(res_list[i].resource_name, warg->name) == 0)
+ {
+ res = &res_list[i];
+ break;
+ }
+
+ if (res == NULL && XtParent(w) != NULL)
+ {
+ XtFree((char *)res_list);
+ XtGetConstraintResourceList(XtClass(XtParent(w)), &res_list, &num_res);
+ for (i = 0; i < num_res; i++)
+ if (strcmp(res_list[i].resource_name, warg->name) == 0)
+ {
+ res = &res_list[i];
+ break;
+ }
+ }
+
+ if (res == NULL)
+ {
+ /* Couldn't find resource */
+
+ XtFree((char *)res_list);
+ *(XtPointer *)warg->value = NULL;
+ return;
+ }
+
+ /* try to get the value in the proper size */
+ switch (res->resource_size)
+ {
+#ifdef LONG64
+ long v8;
+#endif
+ int v4;
+ short v2;
+ char v1;
+
+ case 1:
+ XtSetArg(args[0], res->resource_name, &v1);
+ XtGetValues(w, args, 1);
+ value = (int)v1;
+ break;
+ case 2:
+ XtSetArg(args[0], res->resource_name, &v2);
+ XtGetValues(w, args, 1);
+ value = (int)v2;
+ break;
+ case 4:
+ XtSetArg(args[0], res->resource_name, &v4);
+ XtGetValues(w, args, 1);
+ value = (int)v4;
+ break;
+#ifdef LONG64
+ case 8:
+ XtSetArg(args[0], res->resource_name, &v8);
+ XtGetValues(w, args, 1);
+ value = (long)v8;
+ break;
+#endif
+ default:
+ fprintf(stderr, "_XEditresGetStringValues: bad size %d\n",
+ res->resource_size);
+ string = "bad size";
+ *(char **)(warg->value) = string;
+ XtFree((char *)res_list);
+ return;
+ }
+
+ /*
+ * If the resource is already String, no conversion needed
+ */
+ if (strcmp(XtRString, res->resource_type) == 0)
+ {
+ if (value == 0)
+ string = "(null)";
+ else
+ string = (char *)value;
+ }
+ else
+ {
+ from.size = res->resource_size;
+ from.addr = (XPointer)&value;
+ to.addr = NULL;
+ to.size = 0;
+
+ if (XtConvertAndStore(w,res->resource_type, &from, XtRString, &to))
+ string = to.addr;
+ else
+ {
+ string = buffer;
+ /*
+ * Conversion failed, fall back to representing it as integer
+ */
+ switch (res->resource_size)
+ {
+ case sizeof(char):
+ XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xff));
+ break;
+ case sizeof(short):
+ XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xffff));
+ break;
+ case sizeof(int):
+ XmuSnprintf(buffer, sizeof(buffer), "0x%08x", (int)value);
+ break;
+#ifdef LONG64
+ case sizeof(long):
+ XmuSnprintf(buffer, sizeof(buffer), "0x%016lx", value);
+ break;
+#endif
+ }
+ }
+ }
+
+ if (string == NULL)
+ string = "";
+
+ *(char **)(warg->value) = string;
+ XtFree((char *)res_list);
+}
|