home *** CD-ROM | disk | FTP | other *** search
- /*
- * $XConsortium: utils.c,v 1.17 91/10/09 10:39:44 dave Exp $
- *
- * Copyright 1989 Massachusetts Institute of Technology
- *
- * 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, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <X11/Intrinsic.h>
- #include <X11/Xutil.h>
- #include <X11/Xos.h>
- #include <X11/Shell.h>
- #include <X11/StringDefs.h>
-
- #include <X11/Xaw/Cardinals.h>
- #include <X11/Xaw/Dialog.h>
-
- #include <stdio.h>
-
- #include "editresP.h"
-
- static WidgetResources * ParseResources();
- static int CompareResourceEntries();
- static void FreeResources(), AddResource();
- static WNode * FindWidgetFromWindowGivenNode();
-
- void CreateResourceBox();
-
- extern void PopupCentered(), PerformTreeToFileDump();
-
- /* Function Name: ShowMessage(w, str)
- * Description: shows the message to the user.
- * Arguments: w - a label widget to show the message in.
- * str - the string to show.
- * Returns: none.
- */
-
- void
- SetMessage(w, str)
- Widget w;
- char * str;
- {
- Arg args[1];
-
- XtSetArg(args[0], XtNlabel, str);
- XtSetValues(w, args, ONE);
- }
-
- /* Function Name: GetAllStrings
- * Description: Returns a list of strings that have been borken up by
- * the character specified.
- * Arguments: in - the string to parse.
- * sep - the separator character.
- * out - the strings to send out.
- * num - the number of strings in out.
- * Returns: none
- */
-
- void
- GetAllStrings(in, sep, out, num)
- char *in, sep, ***out;
- int * num;
- {
- int size, i;
- char * ptr;
-
- if (*in == sep) /* jump over first char if it is the sep. */
- in++;
-
- /*
- * count the number of strings.
- */
-
- for (*num = 1, ptr = in; (ptr = index(ptr, sep)) != NULL; (*num)++)
- ptr++;
-
- /*
- * Create Enough space for pointers and string.
- */
-
- size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1));
- *out = (char **) XtMalloc( (Cardinal) size);
-
- ptr = (char *) (*out + *num);
- strcpy(ptr, in);
-
- /*
- * Change all `sep' characters to '\0' and stuff the pointer into
- * the next pointer slot.
- */
-
- i = 1;
- (*out)[0] = ptr;
- while (TRUE) {
- if ((ptr = index(ptr, sep)) == NULL)
- break;
-
- *ptr++ = '\0';
- (*out)[i++] = ptr;
- }
-
- /*
- * If last string is empty then strip it off.
- */
-
- if ( *((*out)[i - 1]) == '\0' )
- (*num)--;
- }
-
- /* Function Name: AddString
- * Description: Mallocs and strcats the string onto the end of
- * the given string.
- * Arguments: str - string to add on to.
- * add - string to add.
- * Returns: none.
- */
-
- void
- AddString(str, add)
- char ** str, *add;
- {
- int len_str, len_add;
- char * ptr;
-
- len_str = ((*str) ? strlen(*str) : 0);
- len_add = strlen(add);
-
- *str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1));
- ptr = *str + len_str;
- strcpy(ptr, add);
- }
-
- /* Function Name: FindNode
- * Description: Finds a node give the top node, and a node id number.
- * Arguments: top_node - the top node.
- * id - the node id.
- * Returns: node.
- */
-
- WNode *
- FindNode(top_node, ids, number)
- WNode *top_node;
- unsigned long * ids;
- Cardinal number;
- {
- int i, j;
- WNode *node;
-
- if (top_node == NULL)
- return(NULL);
-
- if (ids[0] != top_node->id)
- return(NULL);
-
- for (node = top_node, i = 1 ; i < number; i++) {
- Boolean found_it = FALSE;
-
- for (j = 0; j < node->num_children; j++) {
- if (node->children[j]->id == ids[i]) {
- node = node->children[j];
- found_it = TRUE;
- break;
- }
- }
- if (!found_it)
- return(NULL);
- }
- return(node);
- }
-
- /* Function Name: FindWidgetFromWindow
- * Description: finds a widget in the current tree given its window id.
- * Arguments: tree_info - information about this tree.
- * win - window to search for.
- * Returns: node - the node corrosponding to this widget.
- */
-
- WNode *
- FindWidgetFromWindow(tree_info, win)
- TreeInfo * tree_info;
- Window win;
- {
- if (tree_info == NULL)
- return(NULL);
-
- return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
- }
-
- /* Function Name: FindWidgetFromWindowGivenNode
- * Description: finds a widget in the current tree given its window id.
- * Arguments: node - current node.
- * win - window to search for.
- * Returns: node - the node corrosponding to this widget.
- */
-
- static WNode *
- FindWidgetFromWindowGivenNode(node, win)
- WNode * node;
- Window win;
- {
- int i;
- WNode * ret_node;
-
- if (node->window == win)
- return(node);
-
- for (i = 0; i < node->num_children; i++) {
- ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
- if (ret_node != NULL)
- return(ret_node);
- }
- return(NULL);
- }
-
- /* Function Name: HandleXErrors
- * Description: Handles error codes from the server.
- * Arguments: display - the display.
- * error - error information.
- * Returns: none.
- */
-
- /* ARGSUSED */
- int
- HandleXErrors(display, error)
- Display * display;
- XErrorEvent * error;
- {
- if (error->serial != global_serial_num) {
- (*global_old_error_handler) (display, error);
- return(0);
- }
-
- if (error->error_code == BadWindow)
- global_error_code = NO_WINDOW;
- else {
- if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0)
- exit(1);
- }
- return(0);
- }
-
- /* Function Name: _DumpTreeToFile
- * Description: Dumps the widget tree to a file
- * Arguments: w - a random widget in the application on the
- * currently active display
- * tree_ptr - pointer to the widget tree info.
- * filename - name of the file.
- * Returns: none.
- */
-
- /* ARGSUSED */
-
- void
- _DumpTreeToFile(w, tree_ptr, filename)
- Widget w;
- XtPointer tree_ptr;
- char * filename;
- {
- TreeInfo * tree_info = (TreeInfo *) tree_ptr;
- FILE * fp;
-
- if (tree_info == NULL) {
- SetMessage(global_screen_data.info_label,
- "No widget Tree is avaliable.");
- return;
- }
-
- if ( (fp = fopen(filename, "w")) == NULL ) {
- char buf[BUFSIZ];
-
- sprintf(buf, "Unable to open the file `%s' for writing.", filename);
- SetMessage(global_screen_data.info_label, buf);
- return;
- }
-
- PerformTreeToFileDump(tree_info->top_node, 0, fp);
- fclose(fp);
- }
-
- /************************************************************
- *
- * The file dialog boxes are handled with this code.
- *
- * It automatically calls the function specified when the
- * user selects okay, or hits <CR>.
- *
- * A translation is required in the app-defaults file.
- *
- ************************************************************/
-
- /* Function Name: _PopupFileDialog
- * Description: Puts up a dialog box to get the filename.
- * Arguments: str - message.
- * default_value - the default value of the filename;
- * func - function to call when filename has been entered.
- * data - generic data to pass to func.
- * Returns: none
- */
-
- static XContext file_dialog_context = None;
-
- typedef struct _FileDialogInfo {
- void (*func)();
- XtPointer data;
- } FileDialogInfo;
-
- void
- _PopupFileDialog(w, str, default_value, func, data)
- Widget w;
- String str, default_value;
- void (*func)();
- XtPointer data;
- {
- FileDialogInfo * file_info;
- Widget shell, dialog;
- Arg args[2];
- Cardinal num_args;
- void _PopdownFileDialog();
-
- if (file_dialog_context == None)
- file_dialog_context = XUniqueContext();
-
- shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w,
- NULL, ZERO);
-
- num_args = 0;
- XtSetArg(args[num_args], XtNlabel, str); num_args++;
- XtSetArg(args[num_args], XtNvalue, default_value); num_args++;
- dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
- shell, args, num_args);
-
- file_info = XtNew(FileDialogInfo);
-
- file_info->func = func;
- file_info->data = data;
-
- if (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
- (caddr_t) file_info) != 0) {
- SetMessage(global_screen_data.info_label,
- "Error while trying to save Context\nAborting file dialog popup.");
- XtDestroyWidget(shell);
- return;
- }
-
- XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE);
- XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE);
-
- PopupCentered(NULL, shell, XtGrabNone);
- }
-
- /* Function Name: PopupCentered
- * Description: Pops up the window specified under the location passed
- * in the event, or under the cursor.
- * Arguments: event - the event that we should use.
- * w - widget to popup.
- * mode - mode to pop it up in.
- * Returns: none
- */
-
- void
- PopupCentered(event, w, mode)
- XEvent * event;
- Widget w;
- XtGrabKind mode;
- {
- Boolean get_from_cursor = FALSE;
- Arg args[3];
- Cardinal num_args;
- Dimension width, height, b_width;
- int x, y, max_x, max_y;
-
- XtRealizeWidget(w);
-
- if (event == NULL)
- get_from_cursor = TRUE;
- else {
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- x = event->xbutton.x_root;
- y = event->xbutton.y_root;
- break;
- case KeyPress:
- case KeyRelease:
- x = event->xkey.x_root;
- y = event->xkey.y_root;
- break;
- default:
- get_from_cursor = TRUE;
- break;
- }
- }
-
- if (get_from_cursor) {
- Window root, child;
- int win_x, win_y;
- unsigned int mask;
-
- XQueryPointer(XtDisplay(w), XtWindow(w),
- &root, &child, &x, &y, &win_x, &win_y, &mask);
- }
-
- num_args = 0;
- XtSetArg(args[num_args], XtNwidth, &width); num_args++;
- XtSetArg(args[num_args], XtNheight, &height); num_args++;
- XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
- XtGetValues(w, args, num_args);
-
- width += 2 * b_width;
- height += 2 * b_width;
-
- x -= ((int) width/2);
- if (x < 0)
- x = 0;
- if ( x > (max_x = (int) (XtScreen(w)->width - width)) )
- x = max_x;
-
- y -= ( (Position) height/2 );
- if (y < 0)
- y = 0;
- if ( y > (max_y = (int) (XtScreen(w)->height - height)) )
- y = max_y;
-
- num_args = 0;
- XtSetArg(args[num_args], XtNx, x); num_args++;
- XtSetArg(args[num_args], XtNy, y); num_args++;
- XtSetValues(w, args, num_args);
-
- XtPopup(w, mode);
- }
-
- /* Function Name: _PopdownFileDialog
- * Description: Destroys the file dialog, and calls the correct function.
- * Arguments: w - a child of the dialog widget.
- * client_data - TRUE if command was sucessful.
- * junk - ** UNUSED **.
- * Returns: none.
- */
-
- /* ARGSUSED */
-
- void
- _PopdownFileDialog(w, client_data, junk)
- Widget w;
- XtPointer client_data, junk;
- {
- Widget dialog = XtParent(w);
- caddr_t file_info_ptr;
- FileDialogInfo * file_info;
-
- if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
- &file_info_ptr) == XCNOENT) {
- SetMessage(global_screen_data.info_label,
- "Error while trying to find Context\nAborting...");
- }
-
- (void) XDeleteContext(XtDisplay(dialog), (Window)dialog,
- file_dialog_context);
-
- file_info = (FileDialogInfo *) file_info_ptr;
-
- if ( ((Boolean) client_data) == TRUE ) {
- String filename = XawDialogGetValueString(dialog);
-
- (*file_info->func)(w, file_info->data, filename); /* call handler */
- }
-
- XtFree( (XtPointer) file_info); /* Free data. */
-
- XtPopdown(XtParent(dialog));
- XtDestroyWidget(XtParent(dialog)); /* Remove file dialog. */
- }
-
- /************************************************************
- *
- * Functions for dealing with the Resource Box.
- *
- ************************************************************/
-
- /* Function Name: GetNamesAndClasses
- * Description: Gets a list of names and classes for this widget.
- * Arguments: node - this widget's node.
- * names, classes - list of names and classes. ** RETURNED **
- * Returns: none.
- */
-
- void
- GetNamesAndClasses(node, names, classes)
- WNode * node;
- char *** names, ***classes;
- {
- int i, total_widgets;
- WNode * temp = node;
-
- for (total_widgets = 1 ; temp->parent != NULL ;
- total_widgets++, temp = temp->parent) { } /* empty for */
-
- *names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
- *classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
-
- (*names)[total_widgets] = (*classes)[total_widgets] = NULL;
-
- for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) {
- (*names)[i] = node->name;
- (*classes)[i] = node->class;
- }
- }
-
- /* Function Name: HandleGetResources
- * Description: Gets the resources.
- * Arguments: event - the information from the client.
- * Returns: an error message to display.
- */
-
- char *
- HandleGetResources(event)
- Event * event;
- {
- GetResourcesEvent * get_event = (GetResourcesEvent *) event;
- char buf[BUFSIZ], * errors = NULL;
- int i;
- WNode * node;
-
- for (i = 0; i < (int)get_event->num_entries; i++) {
- node = FindNode(global_tree_info->top_node,
- get_event->info[i].widgets.ids,
- get_event->info[i].widgets.num_widgets);
-
- if (node == NULL) {
- sprintf(buf, "Editres Internal Error: Unable to FindNode.\n");
- AddString(&errors, buf);
- continue;
- }
-
- if (node->resources != NULL)
- FreeResources(node->resources);
-
- if (!get_event->info[i].error) {
- node->resources = ParseResources(get_event->info + i, &errors);
- CreateResourceBox(node, &errors);
- }
- else {
- AddString(&errors, get_event->info[i].message);
- AddString(&errors, "\n");
- }
- }
-
- return(errors);
- }
-
- /* Function Name: CreateResourceBox
- * Description: Creates a resource box for the widget specified.
- * Arguments: node - the node of the widget in question.
- * errors - an error string.
- * Returns: none.
- */
-
- void
- CreateResourceBox(node, errors)
- WNode * node;
- char ** errors;
- {
- void CreateResourceBoxWidgets();
- WidgetResources * resources = node->resources;
- char ** names, ** cons_names;
- int i;
-
- if (global_resource_box_up) {
- AddString(errors, "Only one Resource Box can be active at a time.");
- return;
- }
- else
- global_resource_box_up = TRUE;
-
- if (resources->num_normal > 0) {
- names = (char **) XtMalloc(sizeof(char *) *
- (resources->num_normal + 1));
- for (i = 0 ; i < resources->num_normal ; i++)
- names[i] = resources->normal[i].name;
- names[i] = NULL;
- }
- else
- names = NULL;
-
- if (resources->num_constraint > 0) {
- cons_names = (char **) XtMalloc(sizeof(char *) *
- (resources->num_constraint + 1));
-
- for (i = 0 ; i < resources->num_constraint ; i++)
- cons_names[i] = resources->constraint[i].name;
- cons_names[i] = NULL;
- }
- else
- cons_names = NULL;
-
- CreateResourceBoxWidgets(node, names, cons_names);
- }
-
- /* Function Name: ParseResources
- * Description: Parses the resource values returned from the client
- * into a resources structure.
- * Arguments: info - info about a widget's resources.
- * error - where to place error info.
- * Returns: The resource information.
- */
-
- static WidgetResources *
- ParseResources(info, error)
- GetResourcesInfo * info;
- char **error;
- {
- WidgetResources * resources;
- WidgetResourceInfo * normal;
- int i;
-
- resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources));
-
- /*
- * Allocate enough space for both the normal and constraint resources,
- * then add the normal resources from the top, and the constraint resources
- * from the bottom. This assures that enough memory is allocated, and
- * that there is no overlap.
- */
-
- resources->normal = (WidgetResourceInfo *)
- XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources);
-
- normal = resources->normal;
- resources->constraint = resources->normal + info->num_resources - 1;
-
- resources->num_constraint = resources->num_normal = 0;
-
- for (i = 0; i < (int)info->num_resources; i++) {
- switch((int) info->res_info[i].res_type) {
- case NormalResource:
- resources->num_normal++;
- AddResource(info->res_info + i, normal++);
- break;
- case ConstraintResource:
- resources->num_constraint++;
- AddResource(info->res_info + i, resources->constraint--);
- break;
- default:
- {
- char buf[BUFSIZ];
- sprintf(buf, "Unknown resource type %d\n",
- info->res_info[i].res_type);
- AddString(error, buf);
- }
- break;
- }
- }
-
- /*
- * Sort the resources alphabetically.
- */
-
- qsort(resources->normal, resources->num_normal,
- sizeof(WidgetResourceInfo), CompareResourceEntries);
-
- if (resources->num_constraint > 0) {
- resources->constraint++;
- qsort(resources->constraint, resources->num_constraint,
- sizeof(WidgetResourceInfo), CompareResourceEntries);
- }
- else
- resources->constraint = NULL;
-
- return(resources);
- }
-
- /* Function Name: CompareResourceEntries
- * Description: Compares two resource entries.
- * Arguments: e1, e2 - the entries to compare.
- * Returns: an integer >, < or = 0.
- */
-
- static int
- CompareResourceEntries(e1, e2)
- WidgetResourceInfo *e1, *e2;
- {
- return (strcmp(e1->name, e2->name));
- }
-
- /* Function Name: AddResource
- * Description: Parses the resource string a stuffs in individual
- * parts into the resource info struct.
- * Arguments: res_info - the resource info from the event.
- * resource - location to stuff the resource into.
- * Returns: none.
- */
-
- static void
- AddResource(res_info, resource)
- ResourceInfo * res_info;
- WidgetResourceInfo * resource;
- {
- resource->name = res_info->name;
- res_info->name = NULL; /* Keeps it from being deallocated. */
- resource->class = res_info->class;
- res_info->class = NULL; /* Keeps it from being deallocated. */
- resource->type = res_info->type;
- res_info->type = NULL; /* Keeps it from being deallocated. */
- }
-
-
- /* Function Name: FreeResources
- * Description: frees the resource inforation.
- * Arguments: resources.
- * Returns: none.
- */
-
- static void
- FreeResources(resources)
- WidgetResources * resources;
- {
- int i;
-
- if (resources->num_normal > 0) {
- for (i = 0; i < resources->num_normal; i++) {
- XtFree(resources->normal[i].name);
- XtFree(resources->normal[i].class);
- XtFree(resources->normal[i].type);
- }
- XFree((char *)resources->normal);
- }
-
- if (resources->num_constraint > 0) {
- for (i = 0; i < resources->num_constraint; i++) {
- XtFree(resources->constraint[i].name);
- XtFree(resources->constraint[i].class);
- XtFree(resources->constraint[i].type);
- }
- XFree((char *)resources->constraint);
- }
-
- XFree((char *)resources);
- }
-
-
- /* Function Name: CheckDatabase
- * Description: Checks to see if the node is in the database.
- * Arguments: db - the db to check
- * names, clases - names and clases, represented as quarks.
- * Returns: True if this entry is found.
- */
-
- Boolean
- CheckDatabase(db, names, classes)
- XrmDatabase db;
- XrmQuarkList names, classes;
- {
- XrmRepresentation junk;
- XrmValue garbage;
-
- return(XrmQGetResource(db, names, classes, &junk, &garbage));
- }
-
- /* Function Name: Quarkify
- * Description: Quarkifies the string list specifed.
- * Arguments: list - list of strings to quarkify
- * ptr - an additional string to quarkify.
- * Returns: none.
- */
-
- XrmQuarkList
- Quarkify(list, ptr)
- char ** list;
- char * ptr;
- {
- int i;
- char ** tlist;
- XrmQuarkList quarks, tquarks;
-
- for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {}
- if (ptr != NULL)
- i++;
- i++; /* leave space for NULLQUARK */
-
- quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i);
-
- for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++)
- *tquarks = XrmStringToQuark(*tlist);
-
- if (ptr != NULL)
- *tquarks++ = XrmStringToQuark(ptr);
-
- *tquarks = NULLQUARK;
- return(quarks);
- }
-
- /* Function Name: ExecuteOverAllNodes
- * Description: Executes the given function over all nodes.
- * Arguments: top_node - top node of the tree.
- * func - the function to execute.
- * data - a data pointer to pass to the function.
- * Returns: none
- */
-
- void
- ExecuteOverAllNodes(top_node, func, data)
- WNode * top_node;
- void (*func)();
- XtPointer data;
- {
- int i;
-
- (*func)(top_node, data);
-
- for (i = 0; i < top_node->num_children; i++)
- ExecuteOverAllNodes(top_node->children[i], func, data);
- }
-
- /* Function Name: InsertWidgetFromNode
- * Description: Inserts the widget info for this widget represented
- * by this node.
- * Arguments: stream - the stream to insert it info into.
- * none - the widget node to insert.
- * Returns: none
- */
-
- void
- InsertWidgetFromNode(stream, node)
- ProtocolStream * stream;
- WNode * node;
- {
- WNode *temp;
- unsigned long * widget_list;
- register int i, num_widgets;
-
- for (temp = node, i = 0; temp != 0; temp = temp->parent, 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 = node; temp != 0; temp = temp->parent, i--)
- widget_list[i] = temp->id;
-
- _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);
- }
-
- /* Function Name: GetFailureMesssage
- * Description: returns the message returned from a failed request.
- * Arguments: stream - the protocol stream containing the message.
- * Returns: message to show.
- */
-
- char *
- GetFailureMessage(stream)
- ProtocolStream * stream;
- {
- char * return_str;
-
- if (_XEditResGetString8(stream, &return_str))
- return(return_str);
-
- return(XtNewString("Unable to unpack protocol request."));
- }
-
- /* Function Name: ProtocolFailure
- * Description: Gets the version of the protocol the client is
- * willing to speak.
- * Arguments: stream - the protocol stream containing the message.
- * Returns: message to show.
- */
-
- char *
- ProtocolFailure(stream)
- ProtocolStream * stream;
- {
- char buf[BUFSIZ];
- unsigned char version;
-
- if (!_XEditResGet8(stream, &version))
- return(XtNewString("Unable to unpack protocol request."));
-
- sprintf(buf, "This version of editres uses protocol version %d.\n%s%d",
- CURRENT_PROTOCOL_VERSION,
- "But the client speaks version ", (int) version);
- return(XtNewString(buf));
- }
-
-