utils.c revision 33c89af1
133c89af1Smrg/*
233c89af1Smrg * $Xorg: utils.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
333c89af1Smrg *
433c89af1SmrgCopyright 1989, 1998  The Open Group
533c89af1Smrg
633c89af1SmrgPermission to use, copy, modify, distribute, and sell this software and its
733c89af1Smrgdocumentation for any purpose is hereby granted without fee, provided that
833c89af1Smrgthe above copyright notice appear in all copies and that both that
933c89af1Smrgcopyright notice and this permission notice appear in supporting
1033c89af1Smrgdocumentation.
1133c89af1Smrg
1233c89af1SmrgThe above copyright notice and this permission notice shall be included in
1333c89af1Smrgall copies or substantial portions of the Software.
1433c89af1Smrg
1533c89af1SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1633c89af1SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1733c89af1SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1833c89af1SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1933c89af1SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2033c89af1SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2133c89af1Smrg
2233c89af1SmrgExcept as contained in this notice, the name of The Open Group shall not be
2333c89af1Smrgused in advertising or otherwise to promote the sale, use or other dealings
2433c89af1Smrgin this Software without prior written authorization from The Open Group.
2533c89af1Smrg */
2633c89af1Smrg/* $XFree86: xc/programs/editres/utils.c,v 1.5 2001/04/01 14:00:17 tsi Exp $ */
2733c89af1Smrg
2833c89af1Smrg#include <X11/Intrinsic.h>
2933c89af1Smrg#include <X11/Xutil.h>
3033c89af1Smrg#include <X11/Xos.h>
3133c89af1Smrg#include <X11/Shell.h>
3233c89af1Smrg#include <X11/StringDefs.h>
3333c89af1Smrg
3433c89af1Smrg#include <X11/Xaw/Cardinals.h>
3533c89af1Smrg#include <X11/Xaw/Dialog.h>
3633c89af1Smrg
3733c89af1Smrg#include <stdio.h>
3833c89af1Smrg#include <stdlib.h>
3933c89af1Smrg#include <X11/Xmu/Error.h>
4033c89af1Smrg
4133c89af1Smrg#include "editresP.h"
4233c89af1Smrg
4333c89af1Smrgstatic WNode * FindWidgetFromWindowGivenNode ( WNode * node, Window win );
4433c89af1Smrgstatic WidgetResources * ParseResources ( GetResourcesInfo * info,
4533c89af1Smrg					  char **error );
4633c89af1Smrgstatic int CompareResourceEntries ( const void *e1,
4733c89af1Smrg				    const void *e2 );
4833c89af1Smrgstatic void AddResource ( ResourceInfo * res_info,
4933c89af1Smrg			  WidgetResourceInfo * resource );
5033c89af1Smrgstatic void FreeResources ( WidgetResources * resources );
5133c89af1Smrg
5233c89af1Smrg
5333c89af1Smrg/*	Function Name: SetMessage(w, str)
5433c89af1Smrg *	Description: shows the message to the user.
5533c89af1Smrg *	Arguments: w - a label widget to show the message in.
5633c89af1Smrg *                 str - the string to show.
5733c89af1Smrg *	Returns: none.
5833c89af1Smrg */
5933c89af1Smrg
6033c89af1Smrgvoid
6133c89af1SmrgSetMessage(w, str)
6233c89af1SmrgWidget w;
6333c89af1Smrgchar * str;
6433c89af1Smrg{
6533c89af1Smrg    Arg args[1];
6633c89af1Smrg
6733c89af1Smrg    XtSetArg(args[0], XtNlabel, str);
6833c89af1Smrg    XtSetValues(w, args, ONE);
6933c89af1Smrg}
7033c89af1Smrg
7133c89af1Smrg/*	Function Name: GetAllStrings
7233c89af1Smrg *	Description: Returns a list of strings that have been borken up by
7333c89af1Smrg *                   the character specified.
7433c89af1Smrg *	Arguments: in - the string to parse.
7533c89af1Smrg *                 sep - the separator character.
7633c89af1Smrg *                 out - the strings to send out.
7733c89af1Smrg *                 num - the number of strings in out.
7833c89af1Smrg *	Returns: none
7933c89af1Smrg */
8033c89af1Smrg
8133c89af1Smrgvoid
8233c89af1SmrgGetAllStrings(char *in, char sep, char ***out, int *num)
8333c89af1Smrg{
8433c89af1Smrg    int size, i;
8533c89af1Smrg    char * ptr;
8633c89af1Smrg
8733c89af1Smrg    if (*in == sep)		/* jump over first char if it is the sep. */
8833c89af1Smrg	in++;
8933c89af1Smrg
9033c89af1Smrg    /*
9133c89af1Smrg     * count the number of strings.
9233c89af1Smrg     */
9333c89af1Smrg
9433c89af1Smrg    for (*num = 1, ptr = in; (ptr = strchr(ptr, sep)) != NULL; (*num)++)
9533c89af1Smrg	ptr++;
9633c89af1Smrg
9733c89af1Smrg/*
9833c89af1Smrg * Create Enough space for pointers and string.
9933c89af1Smrg */
10033c89af1Smrg
10133c89af1Smrg    size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1));
10233c89af1Smrg    *out = (char **) XtMalloc( (Cardinal) size);
10333c89af1Smrg
10433c89af1Smrg    ptr = (char *) (*out + *num);
10533c89af1Smrg    strcpy(ptr, in);
10633c89af1Smrg
10733c89af1Smrg/*
10833c89af1Smrg * Change all `sep' characters to '\0' and stuff the pointer into
10933c89af1Smrg * the next pointer slot.
11033c89af1Smrg */
11133c89af1Smrg
11233c89af1Smrg    i = 1;
11333c89af1Smrg    (*out)[0] = ptr;
11433c89af1Smrg    while (TRUE) {
11533c89af1Smrg	if ((ptr = strchr(ptr, sep)) == NULL)
11633c89af1Smrg	    break;
11733c89af1Smrg
11833c89af1Smrg	*ptr++ = '\0';
11933c89af1Smrg	(*out)[i++] = ptr;
12033c89af1Smrg    }
12133c89af1Smrg
12233c89af1Smrg/*
12333c89af1Smrg * If last string is empty then strip it off.
12433c89af1Smrg */
12533c89af1Smrg
12633c89af1Smrg    if ( *((*out)[i - 1]) == '\0' )
12733c89af1Smrg	(*num)--;
12833c89af1Smrg}
12933c89af1Smrg
13033c89af1Smrg/*	Function Name: AddString
13133c89af1Smrg *	Description: Mallocs and strcats the string onto the end of
13233c89af1Smrg *                   the given string.
13333c89af1Smrg *	Arguments: str - string to add on to.
13433c89af1Smrg *                 add - string to add.
13533c89af1Smrg *	Returns: none.
13633c89af1Smrg */
13733c89af1Smrg
13833c89af1Smrgvoid
13933c89af1SmrgAddString(str, add)
14033c89af1Smrgchar ** str, *add;
14133c89af1Smrg{
14233c89af1Smrg    int len_str, len_add;
14333c89af1Smrg    char * ptr;
14433c89af1Smrg
14533c89af1Smrg    len_str = ((*str) ? strlen(*str) : 0);
14633c89af1Smrg    len_add = strlen(add);
14733c89af1Smrg
14833c89af1Smrg    *str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1));
14933c89af1Smrg    ptr = *str + len_str;
15033c89af1Smrg    strcpy(ptr, add);
15133c89af1Smrg}
15233c89af1Smrg
15333c89af1Smrg/*	Function Name: FindNode
15433c89af1Smrg *	Description: Finds a node give the top node, and a node id number.
15533c89af1Smrg *	Arguments: top_node - the top node.
15633c89af1Smrg *                 id - the node id.
15733c89af1Smrg *	Returns: node.
15833c89af1Smrg */
15933c89af1Smrg
16033c89af1SmrgWNode *
16133c89af1SmrgFindNode(top_node, ids, number)
16233c89af1SmrgWNode *top_node;
16333c89af1Smrgunsigned long * ids;
16433c89af1SmrgCardinal number;
16533c89af1Smrg{
16633c89af1Smrg    int i, j;
16733c89af1Smrg    WNode *node;
16833c89af1Smrg
16933c89af1Smrg    if (top_node == NULL)
17033c89af1Smrg	return(NULL);
17133c89af1Smrg
17233c89af1Smrg    if (ids[0] != top_node->id)
17333c89af1Smrg	return(NULL);
17433c89af1Smrg
17533c89af1Smrg    for (node = top_node, i = 1 ; i < number; i++) {
17633c89af1Smrg	Boolean found_it = FALSE;
17733c89af1Smrg
17833c89af1Smrg	for (j = 0; j < node->num_children; j++) {
17933c89af1Smrg	    if (node->children[j]->id == ids[i]) {
18033c89af1Smrg		node = node->children[j];
18133c89af1Smrg		found_it = TRUE;
18233c89af1Smrg		break;
18333c89af1Smrg	    }
18433c89af1Smrg	}
18533c89af1Smrg	if (!found_it)
18633c89af1Smrg	    return(NULL);
18733c89af1Smrg    }
18833c89af1Smrg    return(node);
18933c89af1Smrg}
19033c89af1Smrg
19133c89af1Smrg/*	Function Name: FindWidgetFromWindow
19233c89af1Smrg *	Description: finds a widget in the current tree given its window id.
19333c89af1Smrg *	Arguments: tree_info - information about this tree.
19433c89af1Smrg *                 win - window to search for.
19533c89af1Smrg *	Returns: node - the node corrosponding to this widget.
19633c89af1Smrg */
19733c89af1Smrg
19833c89af1SmrgWNode *
19933c89af1SmrgFindWidgetFromWindow(tree_info, win)
20033c89af1SmrgTreeInfo * tree_info;
20133c89af1SmrgWindow win;
20233c89af1Smrg{
20333c89af1Smrg    if (tree_info == NULL)
20433c89af1Smrg	return(NULL);
20533c89af1Smrg
20633c89af1Smrg    return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
20733c89af1Smrg}
20833c89af1Smrg
20933c89af1Smrg/*	Function Name: FindWidgetFromWindowGivenNode
21033c89af1Smrg *	Description: finds a widget in the current tree given its window id.
21133c89af1Smrg *	Arguments: node - current node.
21233c89af1Smrg *                 win - window to search for.
21333c89af1Smrg *	Returns: node - the node corrosponding to this widget.
21433c89af1Smrg */
21533c89af1Smrg
21633c89af1Smrgstatic WNode *
21733c89af1SmrgFindWidgetFromWindowGivenNode(node, win)
21833c89af1SmrgWNode * node;
21933c89af1SmrgWindow win;
22033c89af1Smrg{
22133c89af1Smrg    int i;
22233c89af1Smrg    WNode * ret_node;
22333c89af1Smrg
22433c89af1Smrg    if (node->window == win)
22533c89af1Smrg	return(node);
22633c89af1Smrg
22733c89af1Smrg    for (i = 0; i < node->num_children; i++) {
22833c89af1Smrg	ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
22933c89af1Smrg	if (ret_node != NULL)
23033c89af1Smrg	    return(ret_node);
23133c89af1Smrg    }
23233c89af1Smrg    return(NULL);
23333c89af1Smrg}
23433c89af1Smrg
23533c89af1Smrg/*	Function Name: HandleXErrors
23633c89af1Smrg *	Description: Handles error codes from the server.
23733c89af1Smrg *	Arguments: display - the display.
23833c89af1Smrg *                 error - error information.
23933c89af1Smrg *	Returns: none.
24033c89af1Smrg */
24133c89af1Smrg
24233c89af1Smrg/* ARGSUSED */
24333c89af1Smrgint
24433c89af1SmrgHandleXErrors(display, error)
24533c89af1SmrgDisplay * display;
24633c89af1SmrgXErrorEvent * error;
24733c89af1Smrg{
24833c89af1Smrg    if (error->serial != global_serial_num) {
24933c89af1Smrg	(*global_old_error_handler) (display, error);
25033c89af1Smrg	return(0);
25133c89af1Smrg    }
25233c89af1Smrg
25333c89af1Smrg    if (error->error_code == BadWindow)
25433c89af1Smrg	global_error_code = NO_WINDOW;
25533c89af1Smrg    else {
25633c89af1Smrg	if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0)
25733c89af1Smrg	    exit(1);
25833c89af1Smrg    }
25933c89af1Smrg    return(0);
26033c89af1Smrg}
26133c89af1Smrg
26233c89af1Smrg/*	Function Name: _DumpTreeToFile
26333c89af1Smrg *	Description: Dumps the widget tree to a file
26433c89af1Smrg *	Arguments: w - a random widget in the application on the
26533c89af1Smrg *                     currently active display
26633c89af1Smrg *                 tree_ptr - pointer to the widget tree info.
26733c89af1Smrg *                 filename - name of the file.
26833c89af1Smrg *	Returns: none.
26933c89af1Smrg */
27033c89af1Smrg
27133c89af1Smrg/* ARGSUSED */
27233c89af1Smrg
27333c89af1Smrgvoid
27433c89af1Smrg_DumpTreeToFile(w, tree_ptr, filename)
27533c89af1SmrgWidget w;
27633c89af1SmrgXtPointer tree_ptr;
27733c89af1SmrgXtPointer filename;
27833c89af1Smrg{
27933c89af1Smrg    TreeInfo * tree_info = (TreeInfo *) tree_ptr;
28033c89af1Smrg    FILE * fp;
28133c89af1Smrg
28233c89af1Smrg    if (tree_info == NULL) {
28333c89af1Smrg	SetMessage(global_screen_data.info_label,
28433c89af1Smrg		   res_labels[17]);
28533c89af1Smrg	return;
28633c89af1Smrg    }
28733c89af1Smrg
28833c89af1Smrg    if ( (fp = fopen((char *)filename, "w")) == NULL ) {
28933c89af1Smrg	char buf[BUFSIZ];
29033c89af1Smrg
29133c89af1Smrg	sprintf(buf, res_labels[24], (char *)filename);
29233c89af1Smrg	SetMessage(global_screen_data.info_label, buf);
29333c89af1Smrg	return;
29433c89af1Smrg    }
29533c89af1Smrg
29633c89af1Smrg    PerformTreeToFileDump(tree_info->top_node, 0, fp);
29733c89af1Smrg    fclose(fp);
29833c89af1Smrg}
29933c89af1Smrg
30033c89af1Smrg/************************************************************
30133c89af1Smrg *
30233c89af1Smrg * The file dialog boxes are handled with this code.
30333c89af1Smrg *
30433c89af1Smrg * It automatically calls the function specified when the
30533c89af1Smrg * user selects okay, or hits <CR>.
30633c89af1Smrg *
30733c89af1Smrg * A translation is required in the app-defaults file.
30833c89af1Smrg *
30933c89af1Smrg ************************************************************/
31033c89af1Smrg
31133c89af1Smrg/*	Function Name: _PopupFileDialog
31233c89af1Smrg *	Description: Puts up a dialog box to get the filename.
31333c89af1Smrg *	Arguments: str - message.
31433c89af1Smrg *                 default_value - the default value of the filename;
31533c89af1Smrg *                 func - function to call when filename has been entered.
31633c89af1Smrg *                 data - generic data to pass to func.
31733c89af1Smrg *	Returns: none
31833c89af1Smrg */
31933c89af1Smrg
32033c89af1Smrgstatic XContext file_dialog_context = None;
32133c89af1Smrg
32233c89af1Smrgtypedef struct _FileDialogInfo {
32333c89af1Smrg    XtCallbackProc func;
32433c89af1Smrg    XtPointer data;
32533c89af1Smrg} FileDialogInfo;
32633c89af1Smrg
32733c89af1Smrgvoid
32833c89af1Smrg_PopupFileDialog(w, str, default_value, func, data)
32933c89af1SmrgWidget w;
33033c89af1SmrgString str, default_value;
33133c89af1SmrgXtCallbackProc func;
33233c89af1SmrgXtPointer data;
33333c89af1Smrg{
33433c89af1Smrg    FileDialogInfo * file_info;
33533c89af1Smrg    Widget shell, dialog;
33633c89af1Smrg    Arg args[2];
33733c89af1Smrg    Cardinal num_args;
33833c89af1Smrg
33933c89af1Smrg    if (file_dialog_context == None)
34033c89af1Smrg	file_dialog_context = XUniqueContext();
34133c89af1Smrg
34233c89af1Smrg    shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w,
34333c89af1Smrg			       NULL, ZERO);
34433c89af1Smrg
34533c89af1Smrg    num_args = 0;
34633c89af1Smrg    XtSetArg(args[num_args], XtNlabel, str); num_args++;
34733c89af1Smrg    XtSetArg(args[num_args], XtNvalue, default_value); num_args++;
34833c89af1Smrg    dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
34933c89af1Smrg				   shell, args, num_args);
35033c89af1Smrg
35133c89af1Smrg    file_info = XtNew(FileDialogInfo);
35233c89af1Smrg
35333c89af1Smrg    file_info->func = func;
35433c89af1Smrg    file_info->data = data;
35533c89af1Smrg
35633c89af1Smrg    if  (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
35733c89af1Smrg		      (XPointer) file_info) != 0) {
35833c89af1Smrg	SetMessage(global_screen_data.info_label,
35933c89af1Smrg	    "Error while trying to save Context\nAborting file dialog popup.");
36033c89af1Smrg	XtDestroyWidget(shell);
36133c89af1Smrg	return;
36233c89af1Smrg    }
36333c89af1Smrg
36433c89af1Smrg    XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE);
36533c89af1Smrg    XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE);
36633c89af1Smrg
36733c89af1Smrg    PopupCentered(NULL, shell, XtGrabNone);
36833c89af1Smrg}
36933c89af1Smrg
37033c89af1Smrg/*	Function Name: PopupCentered
37133c89af1Smrg *	Description: Pops up the window specified under the location passed
37233c89af1Smrg *                   in the event, or under the cursor.
37333c89af1Smrg *	Arguments: event - the event that we should use.
37433c89af1Smrg *                 w - widget to popup.
37533c89af1Smrg *                 mode - mode to pop it up in.
37633c89af1Smrg *	Returns: none
37733c89af1Smrg */
37833c89af1Smrg
37933c89af1Smrgvoid
38033c89af1SmrgPopupCentered(event, w, mode)
38133c89af1SmrgXEvent * event;
38233c89af1SmrgWidget w;
38333c89af1SmrgXtGrabKind mode;
38433c89af1Smrg{
38533c89af1Smrg    Boolean get_from_cursor = FALSE;
38633c89af1Smrg    Arg args[3];
38733c89af1Smrg    Cardinal num_args;
38833c89af1Smrg    Dimension width, height, b_width;
38933c89af1Smrg    int x, y, max_x, max_y;
39033c89af1Smrg
39133c89af1Smrg    XtRealizeWidget(w);
39233c89af1Smrg
39333c89af1Smrg    if (event == NULL)
39433c89af1Smrg	get_from_cursor = TRUE;
39533c89af1Smrg    else {
39633c89af1Smrg	switch (event->type) {
39733c89af1Smrg	case ButtonPress:
39833c89af1Smrg	case ButtonRelease:
39933c89af1Smrg	    x = event->xbutton.x_root;
40033c89af1Smrg	    y = event->xbutton.y_root;
40133c89af1Smrg	    break;
40233c89af1Smrg	case KeyPress:
40333c89af1Smrg	case KeyRelease:
40433c89af1Smrg	    x = event->xkey.x_root;
40533c89af1Smrg	    y = event->xkey.y_root;
40633c89af1Smrg	    break;
40733c89af1Smrg	default:
40833c89af1Smrg	    get_from_cursor = TRUE;
40933c89af1Smrg	    break;
41033c89af1Smrg	}
41133c89af1Smrg    }
41233c89af1Smrg
41333c89af1Smrg    if (get_from_cursor) {
41433c89af1Smrg	Window root, child;
41533c89af1Smrg	int win_x, win_y;
41633c89af1Smrg	unsigned int mask;
41733c89af1Smrg
41833c89af1Smrg	XQueryPointer(XtDisplay(w), XtWindow(w),
41933c89af1Smrg		      &root, &child, &x, &y, &win_x, &win_y, &mask);
42033c89af1Smrg    }
42133c89af1Smrg
42233c89af1Smrg    num_args = 0;
42333c89af1Smrg    XtSetArg(args[num_args], XtNwidth, &width); num_args++;
42433c89af1Smrg    XtSetArg(args[num_args], XtNheight, &height); num_args++;
42533c89af1Smrg    XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
42633c89af1Smrg    XtGetValues(w, args, num_args);
42733c89af1Smrg
42833c89af1Smrg    width += 2 * b_width;
42933c89af1Smrg    height += 2 * b_width;
43033c89af1Smrg
43133c89af1Smrg    x -= ((int) width/2);
43233c89af1Smrg    if (x < 0)
43333c89af1Smrg	x = 0;
43433c89af1Smrg    if ( x > (max_x = (int) (XtScreen(w)->width - width)) )
43533c89af1Smrg	x = max_x;
43633c89af1Smrg
43733c89af1Smrg    y -= ( (Position) height/2 );
43833c89af1Smrg    if (y < 0)
43933c89af1Smrg	y = 0;
44033c89af1Smrg    if ( y > (max_y = (int) (XtScreen(w)->height - height)) )
44133c89af1Smrg	y = max_y;
44233c89af1Smrg
44333c89af1Smrg    num_args = 0;
44433c89af1Smrg    XtSetArg(args[num_args], XtNx, x); num_args++;
44533c89af1Smrg    XtSetArg(args[num_args], XtNy, y); num_args++;
44633c89af1Smrg    XtSetValues(w, args, num_args);
44733c89af1Smrg
44833c89af1Smrg    XtPopup(w, mode);
44933c89af1Smrg}
45033c89af1Smrg
45133c89af1Smrg/*	Function Name: _PopdownFileDialog
45233c89af1Smrg *	Description: Destroys the file dialog, and calls the correct function.
45333c89af1Smrg *	Arguments:  w - a child of the dialog widget.
45433c89af1Smrg *                  client_data - TRUE if command was sucessful.
45533c89af1Smrg *                  junk - ** UNUSED **.
45633c89af1Smrg *	Returns: none.
45733c89af1Smrg */
45833c89af1Smrg
45933c89af1Smrg/* ARGSUSED */
46033c89af1Smrg
46133c89af1Smrgvoid
46233c89af1Smrg_PopdownFileDialog(w, client_data, junk)
46333c89af1SmrgWidget w;
46433c89af1SmrgXtPointer client_data, junk;
46533c89af1Smrg{
46633c89af1Smrg    Widget dialog = XtParent(w);
46733c89af1Smrg    XPointer file_info_ptr;
46833c89af1Smrg    FileDialogInfo * file_info;
46933c89af1Smrg
47033c89af1Smrg    if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
47133c89af1Smrg		     &file_info_ptr) == XCNOENT) {
47233c89af1Smrg	SetMessage(global_screen_data.info_label,
47333c89af1Smrg		   "Error while trying to find Context\nAborting...");
47433c89af1Smrg    }
47533c89af1Smrg
47633c89af1Smrg    (void) XDeleteContext(XtDisplay(dialog), (Window)dialog,
47733c89af1Smrg			  file_dialog_context);
47833c89af1Smrg
47933c89af1Smrg    file_info = (FileDialogInfo *) file_info_ptr;
48033c89af1Smrg
48133c89af1Smrg    if ( ((Boolean)(long) client_data) == TRUE ) {
48233c89af1Smrg	String filename = XawDialogGetValueString(dialog);
48333c89af1Smrg
48433c89af1Smrg	(*file_info->func)(w, file_info->data, filename); /* call handler */
48533c89af1Smrg    }
48633c89af1Smrg
48733c89af1Smrg    XtFree( (XtPointer) file_info); /* Free data. */
48833c89af1Smrg
48933c89af1Smrg    XtPopdown(XtParent(dialog));
49033c89af1Smrg    XtDestroyWidget(XtParent(dialog)); /* Remove file dialog. */
49133c89af1Smrg}
49233c89af1Smrg
49333c89af1Smrg/************************************************************
49433c89af1Smrg *
49533c89af1Smrg * Functions for dealing with the Resource Box.
49633c89af1Smrg *
49733c89af1Smrg ************************************************************/
49833c89af1Smrg
49933c89af1Smrg/*    Function Name: GetNamesAndClasses
50033c89af1Smrg *    Description: Gets a list of names and classes for this widget.
50133c89af1Smrg *    Arguments: node - this widget's node.
50233c89af1Smrg *                 names, classes - list of names and classes. ** RETURNED **
50333c89af1Smrg *    Returns: none.
50433c89af1Smrg */
50533c89af1Smrg
50633c89af1Smrgvoid
50733c89af1SmrgGetNamesAndClasses(node, names, classes)
50833c89af1SmrgWNode * node;
50933c89af1Smrgchar *** names, ***classes;
51033c89af1Smrg{
51133c89af1Smrg    int i, total_widgets;
51233c89af1Smrg    WNode * temp = node;
51333c89af1Smrg
51433c89af1Smrg    for (total_widgets = 1 ; temp->parent != NULL ;
51533c89af1Smrg       total_widgets++, temp = temp->parent) {}
51633c89af1Smrg
51733c89af1Smrg    *names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
51833c89af1Smrg    *classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
51933c89af1Smrg
52033c89af1Smrg    (*names)[total_widgets] = (*classes)[total_widgets] = NULL;
52133c89af1Smrg
52233c89af1Smrg    for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) {
52333c89af1Smrg      (*names)[i] = node->name;
52433c89af1Smrg      (*classes)[i] = node->class;
52533c89af1Smrg    }
52633c89af1Smrg}
52733c89af1Smrg
52833c89af1Smrg/*	Function Name: HandleGetResources
52933c89af1Smrg *	Description: Gets the resources.
53033c89af1Smrg *	Arguments: event - the information from the client.
53133c89af1Smrg *	Returns: an error message to display.
53233c89af1Smrg */
53333c89af1Smrg
53433c89af1Smrgchar *
53533c89af1SmrgHandleGetResources(event)
53633c89af1SmrgEvent * event;
53733c89af1Smrg{
53833c89af1Smrg    GetResourcesEvent * get_event = (GetResourcesEvent *) event;
53933c89af1Smrg    char buf[BUFSIZ], * errors = NULL;
54033c89af1Smrg    int i;
54133c89af1Smrg    WNode * node;
54233c89af1Smrg
54333c89af1Smrg    for (i = 0; i < (int)get_event->num_entries; i++) {
54433c89af1Smrg	node = FindNode(global_tree_info->top_node,
54533c89af1Smrg			get_event->info[i].widgets.ids,
54633c89af1Smrg			get_event->info[i].widgets.num_widgets);
54733c89af1Smrg
54833c89af1Smrg	if (node == NULL) {
54933c89af1Smrg	    sprintf(buf, res_labels[16]);
55033c89af1Smrg	    AddString(&errors, buf);
55133c89af1Smrg	    continue;
55233c89af1Smrg	}
55333c89af1Smrg
55433c89af1Smrg	if (node->resources != NULL)
55533c89af1Smrg	    FreeResources(node->resources);
55633c89af1Smrg
55733c89af1Smrg	if (!get_event->info[i].error) {
55833c89af1Smrg	    node->resources = ParseResources(get_event->info + i, &errors);
55933c89af1Smrg	    CreateResourceBox(node, &errors);
56033c89af1Smrg	}
56133c89af1Smrg	else {
56233c89af1Smrg	    AddString(&errors, get_event->info[i].message);
56333c89af1Smrg	    AddString(&errors, "\n");
56433c89af1Smrg	}
56533c89af1Smrg    }
56633c89af1Smrg
56733c89af1Smrg    return(errors);
56833c89af1Smrg}
56933c89af1Smrg
57033c89af1Smrg/*	Function Name: CreateResourceBox
57133c89af1Smrg *	Description: Creates a resource box for the widget specified.
57233c89af1Smrg *	Arguments: node - the node of the widget in question.
57333c89af1Smrg *                 errors - an error string.
57433c89af1Smrg *	Returns: none.
57533c89af1Smrg */
57633c89af1Smrg
57733c89af1Smrgvoid
57833c89af1SmrgCreateResourceBox(node, errors)
57933c89af1SmrgWNode * node;
58033c89af1Smrgchar ** errors;
58133c89af1Smrg{
58233c89af1Smrg    WidgetResources * resources = node->resources;
58333c89af1Smrg    char ** names, ** cons_names;
58433c89af1Smrg    int i;
58533c89af1Smrg
58633c89af1Smrg    if (global_resource_box_up) {
58733c89af1Smrg	AddString(errors, res_labels[34]);
58833c89af1Smrg	return;
58933c89af1Smrg    }
59033c89af1Smrg    else
59133c89af1Smrg	global_resource_box_up = TRUE;
59233c89af1Smrg
59333c89af1Smrg    if (resources->num_normal > 0) {
59433c89af1Smrg	names = (char **) XtMalloc(sizeof(char *) *
59533c89af1Smrg				   (resources->num_normal + 1));
59633c89af1Smrg	for (i = 0 ; i < resources->num_normal ; i++)
59733c89af1Smrg	    names[i] = resources->normal[i].name;
59833c89af1Smrg	names[i] = NULL;
59933c89af1Smrg    }
60033c89af1Smrg    else
60133c89af1Smrg	names = NULL;
60233c89af1Smrg
60333c89af1Smrg    if (resources->num_constraint > 0) {
60433c89af1Smrg	cons_names = (char **) XtMalloc(sizeof(char *) *
60533c89af1Smrg					(resources->num_constraint + 1));
60633c89af1Smrg
60733c89af1Smrg	for (i = 0 ; i < resources->num_constraint ; i++)
60833c89af1Smrg	    cons_names[i] = resources->constraint[i].name;
60933c89af1Smrg	cons_names[i] = NULL;
61033c89af1Smrg    }
61133c89af1Smrg    else
61233c89af1Smrg	cons_names = NULL;
61333c89af1Smrg
61433c89af1Smrg    CreateResourceBoxWidgets(node, names, cons_names);
61533c89af1Smrg}
61633c89af1Smrg
61733c89af1Smrg/*	Function Name: ParseResources
61833c89af1Smrg *	Description: Parses the resource values returned from the client
61933c89af1Smrg *                   into a resources structure.
62033c89af1Smrg *	Arguments: info - info about a widget's resources.
62133c89af1Smrg *                 error - where to place error info.
62233c89af1Smrg *	Returns: The resource information.
62333c89af1Smrg */
62433c89af1Smrg
62533c89af1Smrgstatic WidgetResources *
62633c89af1SmrgParseResources(info, error)
62733c89af1SmrgGetResourcesInfo * info;
62833c89af1Smrgchar **error;
62933c89af1Smrg{
63033c89af1Smrg    WidgetResources * resources;
63133c89af1Smrg    WidgetResourceInfo * normal;
63233c89af1Smrg    int i;
63333c89af1Smrg
63433c89af1Smrg    resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources));
63533c89af1Smrg
63633c89af1Smrg    /*
63733c89af1Smrg     * Allocate enough space for both the normal and constraint resources,
63833c89af1Smrg     * then add the normal resources from the top, and the constraint resources
63933c89af1Smrg     * from the bottom.  This assures that enough memory is allocated, and
64033c89af1Smrg     * that there is no overlap.
64133c89af1Smrg     */
64233c89af1Smrg
64333c89af1Smrg    resources->normal = (WidgetResourceInfo *)
64433c89af1Smrg	            XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources);
64533c89af1Smrg
64633c89af1Smrg    normal = resources->normal;
64733c89af1Smrg    resources->constraint = resources->normal + info->num_resources - 1;
64833c89af1Smrg
64933c89af1Smrg    resources->num_constraint = resources->num_normal = 0;
65033c89af1Smrg
65133c89af1Smrg    for (i = 0; i < (int)info->num_resources; i++) {
65233c89af1Smrg	switch((int) info->res_info[i].res_type) {
65333c89af1Smrg	case NormalResource:
65433c89af1Smrg	    resources->num_normal++;
65533c89af1Smrg	    AddResource(info->res_info + i, normal++);
65633c89af1Smrg	    break;
65733c89af1Smrg	case ConstraintResource:
65833c89af1Smrg	    resources->num_constraint++;
65933c89af1Smrg	    AddResource(info->res_info + i, resources->constraint--);
66033c89af1Smrg	    break;
66133c89af1Smrg	default:
66233c89af1Smrg	    {
66333c89af1Smrg		char buf[BUFSIZ];
66433c89af1Smrg		sprintf(buf, "Unknown resource type %d\n",
66533c89af1Smrg			info->res_info[i].res_type);
66633c89af1Smrg		AddString(error, buf);
66733c89af1Smrg	    }
66833c89af1Smrg	    break;
66933c89af1Smrg	}
67033c89af1Smrg    }
67133c89af1Smrg
67233c89af1Smrg    /*
67333c89af1Smrg     * Sort the resources alphabetically.
67433c89af1Smrg     */
67533c89af1Smrg
67633c89af1Smrg    qsort(resources->normal, resources->num_normal,
67733c89af1Smrg	  sizeof(WidgetResourceInfo), CompareResourceEntries);
67833c89af1Smrg
67933c89af1Smrg    if (resources->num_constraint > 0) {
68033c89af1Smrg	resources->constraint++;
68133c89af1Smrg	qsort(resources->constraint, resources->num_constraint,
68233c89af1Smrg	      sizeof(WidgetResourceInfo), CompareResourceEntries);
68333c89af1Smrg    }
68433c89af1Smrg    else
68533c89af1Smrg	resources->constraint = NULL;
68633c89af1Smrg
68733c89af1Smrg    return(resources);
68833c89af1Smrg}
68933c89af1Smrg
69033c89af1Smrg/*	Function Name: CompareResourceEntries
69133c89af1Smrg *	Description: Compares two resource entries.
69233c89af1Smrg *	Arguments: e1, e2 - the entries to compare.
69333c89af1Smrg *	Returns: an integer >, < or = 0.
69433c89af1Smrg */
69533c89af1Smrg
69633c89af1Smrgstatic int
69733c89af1SmrgCompareResourceEntries(e1, e2)
69833c89af1Smrgconst void *e1, *e2;
69933c89af1Smrg{
70033c89af1Smrg    return (strcmp(((WidgetResourceInfo *)e1)->name,
70133c89af1Smrg		   ((WidgetResourceInfo *)e2)->name));
70233c89af1Smrg}
70333c89af1Smrg
70433c89af1Smrg/*	Function Name: AddResource
70533c89af1Smrg *	Description: Parses the resource string a stuffs in individual
70633c89af1Smrg *                   parts into the resource info struct.
70733c89af1Smrg *	Arguments: res_info - the resource info from the event.
70833c89af1Smrg *                 resource - location to stuff the resource into.
70933c89af1Smrg *	Returns: none.
71033c89af1Smrg */
71133c89af1Smrg
71233c89af1Smrgstatic void
71333c89af1SmrgAddResource(res_info, resource)
71433c89af1SmrgResourceInfo * res_info;
71533c89af1SmrgWidgetResourceInfo * resource;
71633c89af1Smrg{
71733c89af1Smrg    resource->name = res_info->name;
71833c89af1Smrg    res_info->name = NULL;	/* Keeps it from being deallocated. */
71933c89af1Smrg    resource->class = res_info->class;
72033c89af1Smrg    res_info->class = NULL;	/* Keeps it from being deallocated. */
72133c89af1Smrg    resource->type = res_info->type;
72233c89af1Smrg    res_info->type = NULL;	/* Keeps it from being deallocated. */
72333c89af1Smrg}
72433c89af1Smrg
72533c89af1Smrg
72633c89af1Smrg/*	Function Name: FreeResources
72733c89af1Smrg *	Description: frees the resource inforation.
72833c89af1Smrg *	Arguments: resources.
72933c89af1Smrg *	Returns: none.
73033c89af1Smrg */
73133c89af1Smrg
73233c89af1Smrgstatic void
73333c89af1SmrgFreeResources(resources)
73433c89af1SmrgWidgetResources * resources;
73533c89af1Smrg{
73633c89af1Smrg    int i;
73733c89af1Smrg
73833c89af1Smrg    if (resources->num_normal > 0) {
73933c89af1Smrg	for (i = 0; i < resources->num_normal; i++) {
74033c89af1Smrg	    XtFree(resources->normal[i].name);
74133c89af1Smrg	    XtFree(resources->normal[i].class);
74233c89af1Smrg	    XtFree(resources->normal[i].type);
74333c89af1Smrg	}
74433c89af1Smrg	XFree((char *)resources->normal);
74533c89af1Smrg    }
74633c89af1Smrg
74733c89af1Smrg    if (resources->num_constraint > 0) {
74833c89af1Smrg	for (i = 0; i < resources->num_constraint; i++) {
74933c89af1Smrg	    XtFree(resources->constraint[i].name);
75033c89af1Smrg	    XtFree(resources->constraint[i].class);
75133c89af1Smrg	    XtFree(resources->constraint[i].type);
75233c89af1Smrg	}
75333c89af1Smrg	XFree((char *)resources->constraint);
75433c89af1Smrg    }
75533c89af1Smrg
75633c89af1Smrg    XFree((char *)resources);
75733c89af1Smrg}
75833c89af1Smrg
75933c89af1Smrg
76033c89af1Smrg/*	Function Name: CheckDatabase
76133c89af1Smrg *	Description: Checks to see if the node is in the database.
76233c89af1Smrg *	Arguments: db - the db to check
76333c89af1Smrg *                 names, clases - names and clases, represented as quarks.
76433c89af1Smrg *	Returns: True if this entry is found.
76533c89af1Smrg */
76633c89af1Smrg
76733c89af1SmrgBoolean
76833c89af1SmrgCheckDatabase(db, names, classes)
76933c89af1SmrgXrmDatabase db;
77033c89af1SmrgXrmQuarkList names, classes;
77133c89af1Smrg{
77233c89af1Smrg    XrmRepresentation junk;
77333c89af1Smrg    XrmValue garbage;
77433c89af1Smrg
77533c89af1Smrg    return(XrmQGetResource(db, names, classes, &junk, &garbage));
77633c89af1Smrg}
77733c89af1Smrg
77833c89af1Smrg/*	Function Name: Quarkify
77933c89af1Smrg *	Description: Quarkifies the string list specifed.
78033c89af1Smrg *	Arguments: list - list of strings to quarkify
78133c89af1Smrg *                 ptr - an additional string to quarkify.
78233c89af1Smrg *	Returns: none.
78333c89af1Smrg */
78433c89af1Smrg
78533c89af1SmrgXrmQuarkList
78633c89af1SmrgQuarkify(list, ptr)
78733c89af1Smrgchar ** list;
78833c89af1Smrgchar * ptr;
78933c89af1Smrg{
79033c89af1Smrg    int i;
79133c89af1Smrg    char ** tlist;
79233c89af1Smrg    XrmQuarkList quarks, tquarks;
79333c89af1Smrg
79433c89af1Smrg    for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {}
79533c89af1Smrg    if (ptr != NULL)
79633c89af1Smrg	i++;
79733c89af1Smrg    i++;			/* leave space for NULLQUARK */
79833c89af1Smrg
79933c89af1Smrg    quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i);
80033c89af1Smrg
80133c89af1Smrg    for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++)
80233c89af1Smrg	*tquarks = XrmStringToQuark(*tlist);
80333c89af1Smrg
80433c89af1Smrg    if (ptr != NULL)
80533c89af1Smrg	*tquarks++ = XrmStringToQuark(ptr);
80633c89af1Smrg
80733c89af1Smrg    *tquarks = NULLQUARK;
80833c89af1Smrg    return(quarks);
80933c89af1Smrg}
81033c89af1Smrg
81133c89af1Smrg/*	Function Name: ExecuteOverAllNodes
81233c89af1Smrg *	Description: Executes the given function over all nodes.
81333c89af1Smrg *	Arguments: top_node - top node of the tree.
81433c89af1Smrg *                 func - the function to execute.
81533c89af1Smrg *                 data - a data pointer to pass to the function.
81633c89af1Smrg *	Returns: none
81733c89af1Smrg */
81833c89af1Smrg
81933c89af1Smrgvoid
82033c89af1SmrgExecuteOverAllNodes(top_node, func, data)
82133c89af1SmrgWNode * top_node;
82233c89af1Smrgvoid (*func)(WNode *, XtPointer);
82333c89af1SmrgXtPointer data;
82433c89af1Smrg{
82533c89af1Smrg    int i;
82633c89af1Smrg
82733c89af1Smrg    (*func)(top_node, data);
82833c89af1Smrg
82933c89af1Smrg    for (i = 0; i < top_node->num_children; i++)
83033c89af1Smrg	ExecuteOverAllNodes(top_node->children[i], func, data);
83133c89af1Smrg}
83233c89af1Smrg
83333c89af1Smrg/*	Function Name: InsertWidgetFromNode
83433c89af1Smrg *	Description: Inserts the widget info for this widget represented
83533c89af1Smrg *                   by this node.
83633c89af1Smrg *	Arguments: stream - the stream to insert it info into.
83733c89af1Smrg *                 none - the widget node to insert.
83833c89af1Smrg *	Returns: none
83933c89af1Smrg */
84033c89af1Smrg
84133c89af1Smrgvoid
84233c89af1SmrgInsertWidgetFromNode(stream, node)
84333c89af1SmrgProtocolStream * stream;
84433c89af1SmrgWNode * node;
84533c89af1Smrg{
84633c89af1Smrg    WNode *temp;
84733c89af1Smrg    unsigned long * widget_list;
84833c89af1Smrg    register int i, num_widgets;
84933c89af1Smrg
85033c89af1Smrg    for (temp = node, i = 0; temp != 0; temp = temp->parent, i++) {}
85133c89af1Smrg
85233c89af1Smrg    num_widgets = i;
85333c89af1Smrg    widget_list = (unsigned long *)
85433c89af1Smrg	          XtMalloc(sizeof(unsigned long) * num_widgets);
85533c89af1Smrg
85633c89af1Smrg    /*
85733c89af1Smrg     * Put the widgets into the list.
85833c89af1Smrg     * Make sure that they are inserted in the list from parent -> child.
85933c89af1Smrg     */
86033c89af1Smrg
86133c89af1Smrg    for (i--, temp = node; temp != 0; temp = temp->parent, i--)
86233c89af1Smrg	widget_list[i] = temp->id;
86333c89af1Smrg
86433c89af1Smrg    _XEditResPut16(stream, num_widgets);	/* insert number of widgets. */
86533c89af1Smrg    for (i = 0; i < num_widgets; i++) 	/* insert Widgets themselves. */
86633c89af1Smrg	_XEditResPut32(stream, widget_list[i]);
86733c89af1Smrg
86833c89af1Smrg    XtFree((char *)widget_list);
86933c89af1Smrg}
87033c89af1Smrg
87133c89af1Smrg/*	Function Name: GetFailureMesssage
87233c89af1Smrg *	Description: returns the message returned from a failed request.
87333c89af1Smrg *	Arguments: stream - the protocol stream containing the message.
87433c89af1Smrg *	Returns: message to show.
87533c89af1Smrg */
87633c89af1Smrg
87733c89af1Smrgchar *
87833c89af1SmrgGetFailureMessage(stream)
87933c89af1SmrgProtocolStream * stream;
88033c89af1Smrg{
88133c89af1Smrg    char * return_str;
88233c89af1Smrg
88333c89af1Smrg    if (_XEditResGetString8(stream, &return_str))
88433c89af1Smrg	return(return_str);
88533c89af1Smrg
88633c89af1Smrg    return(XtNewString(res_labels[35]));
88733c89af1Smrg}
88833c89af1Smrg
88933c89af1Smrg/*	Function Name: ProtocolFailure
89033c89af1Smrg *	Description: Gets the version of the protocol the client is
89133c89af1Smrg *                   willing to speak.
89233c89af1Smrg *	Arguments: stream - the protocol stream containing the message.
89333c89af1Smrg *	Returns: message to show.
89433c89af1Smrg */
89533c89af1Smrg
89633c89af1Smrgchar *
89733c89af1SmrgProtocolFailure(stream)
89833c89af1SmrgProtocolStream * stream;
89933c89af1Smrg{
90033c89af1Smrg    char buf[BUFSIZ];
90133c89af1Smrg    unsigned char version;
90233c89af1Smrg    char* old_version_string;
90333c89af1Smrg
90433c89af1Smrg    if (!_XEditResGet8(stream, &version))
90533c89af1Smrg	return(XtNewString(res_labels[35]));
90633c89af1Smrg
90733c89af1Smrg    switch ((int)version) {
90833c89af1Smrg    case PROTOCOL_VERSION_ONE_POINT_ZERO: old_version_string = "1.0"; break;
90933c89af1Smrg    default: old_version_string = "1.0";
91033c89af1Smrg    }
91133c89af1Smrg
91233c89af1Smrg    sprintf(buf, res_labels[36],
91333c89af1Smrg	    CURRENT_PROTOCOL_VERSION_STRING, old_version_string);
91433c89af1Smrg    return(XtNewString(buf));
91533c89af1Smrg}
91633c89af1Smrg
917