summaryrefslogtreecommitdiff
path: root/src/Actions.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:48 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:48 +0000
commit81ad93fde745d556aaa3880deabf3674bb3db49e (patch)
tree24120e85c169c58dedc31dfb61df4e533b058b99 /src/Actions.c
parentb6e0280a57c4dfa572770241a42fe6a476109516 (diff)
downloadxorg-lib-libXaw-81ad93fde745d556aaa3880deabf3674bb3db49e.tar.gz
Initial revisionXORG-STABLE
Diffstat (limited to 'src/Actions.c')
-rw-r--r--src/Actions.c1132
1 files changed, 1132 insertions, 0 deletions
diff --git a/src/Actions.c b/src/Actions.c
new file mode 100644
index 0000000..8e51063
--- /dev/null
+++ b/src/Actions.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 1998 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * 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 XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+/* $XFree86: xc/lib/Xaw/Actions.c,v 3.16 2001/10/30 04:56:38 paulo Exp $ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xmd.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/CoreP.h>
+#include <X11/Constraint.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/SysUtil.h>
+#include <X11/Xfuncs.h>
+#include "Private.h"
+
+#ifndef OLDXAW
+
+/*
+ * Definitions
+ */
+#define ERROR -2
+#define END -1
+#define BOOLEAN 0
+#define AND '&'
+#define OR '|'
+#define XOR '^'
+#define NOT '~'
+#define LP '('
+#define RP ')'
+
+/*
+ * Types
+ */
+/* boolean expressions */
+typedef struct _XawEvalInfo {
+ Widget widget;
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ XawParseBooleanProc parse_proc;
+ XEvent *event;
+ char *cp, *lp;
+ int token;
+ Bool value;
+} XawEvalInfo;
+
+/* resources */
+typedef struct _XawActionRes {
+ XrmQuark qname;
+ XrmQuark qtype;
+ Cardinal size;
+} XawActionRes;
+
+struct _XawActionResList {
+ WidgetClass widget_class;
+ XawActionRes **resources;
+ Cardinal num_common_resources;
+ Cardinal num_constraint_resources;
+};
+
+/* variables */
+typedef struct _XawActionVar {
+ XrmQuark qname;
+ XrmQuark qvalue;
+} XawActionVar;
+
+struct _XawActionVarList {
+ Widget widget;
+ Cardinal num_variables;
+ XawActionVar **variables;
+};
+
+/*
+ * Private methods
+ */
+/* expressions */
+static int get_token(XawEvalInfo*);
+static Bool expr(XawEvalInfo*);
+static Bool and(XawEvalInfo*);
+static Bool prim(XawEvalInfo*);
+
+/* resources */
+static String XawConvertActionRes(XawActionResList*, Widget w, String);
+
+static String _XawEscapeActionVarValue(String);
+static String _XawUnescapeActionVarValue(String);
+static XawActionResList *_XawCreateActionResList(WidgetClass);
+static XawActionResList *_XawFindActionResList(WidgetClass);
+static void _XawBindActionResList(XawActionResList*);
+static XawActionRes *_XawFindActionRes(XawActionResList*, Widget, String);
+static int qcmp_action_resource_list(_Xconst void*, _Xconst void*);
+static int bcmp_action_resource_list(_Xconst void*, _Xconst void*);
+static int qcmp_action_resource(_Xconst void*, _Xconst void*);
+static int bcmp_action_resource(_Xconst void*, _Xconst void*);
+
+/* variables */
+static String XawConvertActionVar(XawActionVarList*, String);
+static void XawDeclareActionVar(XawActionVarList*, String, String);
+
+static XawActionVarList *_XawCreateActionVarList(Widget);
+static XawActionVarList *_XawFindActionVarList(Widget);
+static XawActionVar *_XawCreateActionVar(XawActionVarList*, String);
+static XawActionVar *_XawFindActionVar(XawActionVarList*, String);
+static void _XawDestroyActionVarList(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+/* resources */
+static XawActionResList **resource_list;
+static Cardinal num_resource_list;
+
+/* variables */
+static XawActionVarList **variable_list;
+static Cardinal num_variable_list;
+
+/*
+ * Implementation
+ */
+/*
+ * Start of Boolean Expression Evaluation Implementation Code
+ */
+Bool
+XawParseBoolean(Widget w, String param, XEvent *event, Bool *succed)
+{
+ char *tmp = param;
+ int value;
+
+ if (!param)
+ return (False);
+
+ value = (int)strtod(param, &tmp);
+ if (*tmp == '\0')
+ return (value);
+
+ if (XmuCompareISOLatin1(param, "true") == 0
+ || XmuCompareISOLatin1(param, "yes") == 0
+ || XmuCompareISOLatin1(param, "on") == 0
+ || XmuCompareISOLatin1(param, "in") == 0
+ || XmuCompareISOLatin1(param, "up") == 0)
+ return (True);
+ else if (XmuCompareISOLatin1(param, "false") == 0
+ || XmuCompareISOLatin1(param, "no") == 0
+ || XmuCompareISOLatin1(param, "off") == 0
+ || XmuCompareISOLatin1(param, "out") == 0
+ || XmuCompareISOLatin1(param, "down") == 0)
+ ;
+ else if (XmuCompareISOLatin1(param, "my") == 0
+ || XmuCompareISOLatin1(param, "mine") == 0)
+ return (event->xany.window == XtWindow(w));
+ else if (XmuCompareISOLatin1(param, "faked") == 0)
+ return (event->xany.send_event != 0);
+ else
+ *succed = False;
+
+ return (False);
+}
+
+Bool
+XawBooleanExpression(Widget w, String param, XEvent *event)
+{
+ XawEvalInfo info;
+ Bool retval;
+
+ if (!param)
+ return (False);
+
+ info.widget = w;
+
+ info.rlist = XawGetActionResList(XtClass(w));
+ info.vlist = XawGetActionVarList(w);
+
+ /*
+ * Verify widget class, in case we will allow the parse proc procedure
+ * as a widget class element, or if we allow overriding the default
+ * parse boolean proc.
+ */
+ info.parse_proc = XawParseBoolean;
+
+ info.event = event;
+ info.cp = info.lp = param;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Parsing expression \"%s\"\n", param);
+#endif
+
+ (void)get_token(&info);
+ if (info.token == ERROR)
+ return (False);
+ retval = expr(&info);
+
+ return (info.token != ERROR ? retval : False);
+}
+
+static int
+get_token(XawEvalInfo *info)
+{
+ int ch;
+ char *p, name[256];
+
+ info->lp = info->cp;
+
+ /*COSTCOND*/
+ while (1) /* eat white spaces */
+ {
+ ch = *info->cp++;
+ if (isspace(ch))
+ continue;
+ break;
+ }
+
+ switch (ch)
+ {
+ case AND: case OR: case XOR: case NOT: case LP: case RP:
+ return (info->token = ch);
+ }
+
+ /* It's a symbol name, resolve it. */
+ if (ch == XAW_PRIV_VAR_PREFIX || isalnum(ch) || ch == '_' || ch == '\\')
+ {
+ Bool succed = True;
+
+ p = info->cp - 1;
+
+ while ((ch = *info->cp) && (isalnum(ch) || ch == '_'))
+ ++info->cp;
+
+ strncpy(name, p, XawMin((int)sizeof(name) - 1,
+ (unsigned)(info->cp - p)));
+ name[XawMin((int)sizeof(name) -1, info->cp - p)] = '\0';
+
+ if (name[0] == XAW_PRIV_VAR_PREFIX)
+ {
+ String value = XawConvertActionVar(info->vlist, name);
+
+ info->value = info->parse_proc(info->widget, value, info->event,
+ &succed) & 1;
+ }
+ else
+ {
+ info->value = info->parse_proc(info->widget, name, info->event,
+ &succed) & 1;
+ if (!succed)
+ {
+ String value =
+ XawConvertActionRes(info->rlist, info->widget,
+ name[0] == '\\' ? &name[1] : name);
+ /* '\\' may have been used to escape a resource name.
+ */
+
+ succed = True;
+ info->value = info->parse_proc(info->widget, value, info->event,
+ &succed) & 1;
+ if (!succed)
+ {
+ /* not a numeric value or boolean string */
+ info->value = True;
+ succed = True;
+ }
+ }
+ }
+ if (succed)
+ return (info->token = BOOLEAN);
+ }
+ else if (ch == '\0')
+ return (info->token = END);
+
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): bad token \"%c\" at \"%s\"", ch, info->cp - 1);
+
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ }
+
+ return (info->token = ERROR);
+}
+
+static Bool
+expr(XawEvalInfo *info)
+{
+ Bool left = and(info);
+
+ for (;;)
+ switch (info->token)
+ {
+ case OR:
+ (void)get_token(info);
+ left |= and(info);
+ break;
+ case XOR:
+ (void)get_token(info);
+ left ^= and(info);
+ break;
+ default:
+ return (left);
+ }
+ /* NOTREACHED */
+}
+
+static Bool
+and(XawEvalInfo *info)
+{
+ Bool left = prim(info);
+
+ for (;;)
+ switch (info->token)
+ {
+ case AND:
+ (void)get_token(info);
+ left &= prim(info);
+ break;
+ default:
+ return (left);
+ }
+ /* NOTREACHED */
+}
+
+static Bool
+prim(XawEvalInfo *info)
+{
+ Bool e;
+
+ switch (info->token)
+ {
+ case BOOLEAN:
+ e = info->value;
+ (void)get_token(info);
+ return (e);
+ case NOT:
+ (void)get_token(info);
+ return (!prim(info));
+ case LP:
+ (void)get_token(info);
+ e = expr(info);
+ if (info->token != RP)
+ {
+ char msg[256];
+
+ info->token = ERROR;
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): expecting ), at \"%s\"", info->lp);
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ return (False);
+ }
+ (void)get_token(info);
+ return (e);
+ case END:
+ return (True);
+ default:
+ {
+ char msg[256];
+
+ info->token = ERROR;
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): sintax error, at \"%s\"", info->lp);
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ } return (False);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Start of Resources Implementation Code
+ */
+void
+XawSetValuesAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ Arg *arglist;
+ Cardinal num_args, count;
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ XawActionRes *resource;
+ XrmValue from, to;
+ String value;
+ char c_1;
+ short c_2;
+ int c_4;
+#ifdef LONG64
+ long c_8;
+#endif
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("set-values", w, params, num_params);
+ return;
+ }
+
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ rlist = XawGetActionResList(XtClass(w));
+ vlist = XawGetActionVarList(w);
+
+ num_args = 0;
+ arglist = (Arg *)XtMalloc(sizeof(Arg) * ((*num_params) >> 1));
+
+ for (count = 1; count < *num_params; count += 2)
+ {
+ if ((resource = _XawFindActionRes(rlist, w, params[count])) == NULL)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "set-values(): bad resource name \"%s\"",
+ params[count]);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ continue;
+ }
+ value = XawConvertActionVar(vlist, params[count + 1]);
+ from.size = strlen(value) + 1;
+ from.addr = value;
+ to.size = resource->size;
+ switch (to.size)
+ {
+ case 1: to.addr = (XPointer)&c_1; break;
+ case 2: to.addr = (XPointer)&c_2; break;
+ case 4: to.addr = (XPointer)&c_4; break;
+#ifdef LONG64
+ case 8: to.addr = (XPointer)&c_8; break;
+#endif
+ default:
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "set-values(): bad resource size for \"%s\"",
+ params[count]);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ } continue;
+ }
+
+ if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0)
+#ifdef LONG64
+ c_8 = (long)from.addr;
+#else
+ c_4 = (int)from.addr;
+#endif
+ else if (!XtConvertAndStore(w, XtRString, &from,
+ XrmQuarkToString(resource->qtype), &to))
+ continue;
+
+ switch (to.size)
+ {
+ case 1:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_1);
+ break;
+ case 2:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_2);
+ break;
+ case 4:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_4);
+ break;
+#ifdef LONG64
+ case 8:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_8);
+ break;
+#endif
+ }
+ ++num_args;
+ }
+
+ XtSetValues(w, arglist, num_args);
+ XtFree((char *)arglist);
+}
+
+void
+XawGetValuesAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ String value;
+ Cardinal count;
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("get-values", w, params, num_params);
+ return;
+ }
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ rlist = XawGetActionResList(XtClass(w));
+ vlist = XawGetActionVarList(w);
+
+ for (count = 1; count < *num_params; count += 2)
+ {
+ if ((value = XawConvertActionRes(rlist, w, params[count + 1])) == NULL)
+ continue;
+ XawDeclareActionVar(vlist, params[count], value);
+ }
+}
+
+void
+XawDeclareAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ XawActionVarList *vlist;
+ Cardinal count;
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("declare", w, params, num_params);
+ return;
+ }
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ vlist = XawGetActionVarList(w);
+
+ for (count = 1; count < *num_params; count += 2)
+ XawDeclareActionVar(vlist, params[count], params[count + 1]);
+}
+
+void
+XawCallProcAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ String *args;
+ Cardinal num_args;
+
+ if (*num_params < 2)
+ {
+ XawPrintActionErrorMsg("call-proc", w, params, num_params);
+ return;
+ }
+
+ if (*num_params && !XawBooleanExpression(w, params[0], event))
+ return;
+
+ if (*num_params > 2)
+ {
+ args = &params[2];
+ num_args = *num_params - 2;
+ }
+ else
+ {
+ args = NULL;
+ num_args = 0;
+ }
+
+ XtCallActionProc(w, params[1], event, args, num_args);
+}
+
+static String
+XawConvertActionRes(XawActionResList *list, Widget w, String name)
+{
+ XawActionRes *resource;
+ XrmValue from, to;
+ Arg arg;
+ char c_1;
+ short c_2;
+ int c_4;
+#ifdef LONG64
+ long c_8;
+#endif
+
+ if ((resource = _XawFindActionRes(list, w, name)) == NULL)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "convert(): bad resource name \"%s\"", name);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ return (NULL);
+ }
+
+ from.size = resource->size;
+ switch (from.size)
+ {
+ case 1:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_1);
+ break;
+ case 2:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_2);
+ break;
+ case 4:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_4);
+ break;
+#ifdef LONG64
+ case 8:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_8);
+ break;
+#endif
+ default:
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "convert(): bad resource size for \"%s\"", name);
+ XtAppWarning(XtWidgetToApplicationContext(w), name);
+ } return (NULL);
+ }
+
+ XtGetValues(w, &arg, 1);
+ to.size = sizeof(String);
+ to.addr = NULL;
+
+ if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0)
+ to.addr = *(char **)from.addr;
+ else if (!XtConvertAndStore(w, XrmQuarkToString(resource->qtype),
+ &from, XtRString, &to))
+ return (NULL);
+
+ return ((String)to.addr);
+}
+
+void
+XawPrintActionErrorMsg(String action_name, Widget w,
+ String *params, Cardinal *num_params)
+{
+ char msg[1024];
+ unsigned int size, idx;
+
+ size = XmuSnprintf(msg, sizeof(msg), "%s(): bad number of parameters.\n\t(",
+ action_name, action_name);
+
+ idx = 0;
+ while (idx < *num_params - 1 && size < sizeof(msg))
+ size += XmuSnprintf(&msg[size], sizeof(msg) - size, "%s, ",
+ params[idx++]);
+ if (*num_params)
+ XmuSnprintf(&msg[size], sizeof(msg) - size, "%s)", params[idx]);
+ else
+ XmuSnprintf(&msg[size], sizeof(msg) - size, ")");
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+}
+
+XawActionResList *
+XawGetActionResList(WidgetClass wc)
+{
+ XawActionResList *list;
+
+ list = _XawFindActionResList(wc);
+
+ if (!list)
+ list = _XawCreateActionResList(wc);
+
+ return (list);
+}
+
+static int
+qcmp_action_resource_list(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return ((char *)((*(XawActionResList **)left)->widget_class) -
+ (char *)((*(XawActionResList **)right)->widget_class));
+}
+
+static XawActionResList *
+_XawCreateActionResList(WidgetClass wc)
+{
+ XawActionResList *list;
+
+ list = (XawActionResList *)XtMalloc(sizeof(XawActionResList));
+ list->widget_class = wc;
+ list->num_common_resources = list->num_constraint_resources = 0;
+ list->resources = NULL;
+
+ if (!resource_list)
+ {
+ num_resource_list = 1;
+ resource_list = (XawActionResList **)XtMalloc(sizeof(XawActionResList*));
+ resource_list[0] = list;
+ }
+ else
+ {
+ ++num_resource_list;
+ resource_list = (XawActionResList **)XtRealloc((char *)resource_list,
+ sizeof(XawActionResList*)
+ * num_resource_list);
+ resource_list[num_resource_list - 1] = list;
+ qsort(resource_list, num_resource_list, sizeof(XawActionResList*),
+ qcmp_action_resource_list);
+ }
+
+ _XawBindActionResList(list);
+
+ return (list);
+}
+
+static int
+bcmp_action_resource_list(register _Xconst void *wc,
+ register _Xconst void *list)
+{
+ return ((char *)wc - (char *)((*(XawActionResList **)list)->widget_class));
+}
+
+static XawActionResList *
+_XawFindActionResList(WidgetClass wc)
+{
+ XawActionResList **list;
+
+ if (!resource_list)
+ return (NULL);
+
+ list = (XawActionResList **)bsearch(wc, resource_list,
+ num_resource_list,
+ sizeof(XawActionResList*),
+ bcmp_action_resource_list);
+
+ return (list ? *list : NULL);
+}
+
+static int
+qcmp_action_resource(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return (strcmp(XrmQuarkToString((*(XawActionRes **)left)->qname),
+ XrmQuarkToString((*(XawActionRes **)right)->qname)));
+}
+
+static void
+_XawBindActionResList(XawActionResList *list)
+{
+ XtResourceList xt_list, cons_list;
+ Cardinal i, num_xt, num_cons;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating resource list for class \'%s\'\n---------\n",
+ list->widget_class->core_class.class_name);
+#endif
+
+ XtGetResourceList(list->widget_class, &xt_list, &num_xt);
+ XtGetConstraintResourceList(list->widget_class, &cons_list, &num_cons);
+ list->num_common_resources = num_xt;
+ list->num_constraint_resources = num_cons;
+
+ list->resources = (XawActionRes **)
+ XtMalloc(sizeof(XawActionRes*) * (num_xt + num_cons));
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "Common resources\n---\n");
+#endif
+
+ for (i = 0; i < num_xt; i++)
+ {
+ list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
+ list->resources[i]->qname =
+ XrmPermStringToQuark(xt_list[i].resource_name);
+ list->resources[i]->qtype =
+ XrmPermStringToQuark(xt_list[i].resource_type);
+ list->resources[i]->size = xt_list[i].resource_size;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "%-20s\t%-20s\t(%d)\n",
+ xt_list[i].resource_name,
+ xt_list[i].resource_type,
+ xt_list[i].resource_size);
+#endif
+ }
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "---\nContraint resources\n---");
+#endif
+
+ for (; i < num_xt + num_cons; i++)
+ {
+ list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
+ list->resources[i]->qname =
+ XrmPermStringToQuark(cons_list[i - num_xt].resource_name);
+ list->resources[i]->qtype =
+ XrmPermStringToQuark(cons_list[i - num_xt].resource_type);
+ list->resources[i]->size = cons_list[i - num_xt].resource_size;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "%-20s\t%-20s\t(%d)\n",
+ cons_list[i - num_xt].resource_name,
+ cons_list[i - num_xt].resource_type,
+ cons_list[i - num_xt].resource_size);
+#endif
+ }
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "---\n");
+#endif
+
+ XtFree((char *)xt_list);
+ if (cons_list)
+ XtFree((char *)cons_list);
+
+ qsort(list->resources, list->num_common_resources, sizeof(XawActionRes*),
+ qcmp_action_resource);
+ if (num_cons)
+ qsort(&list->resources[num_xt], list->num_constraint_resources,
+ sizeof(XawActionRes*), qcmp_action_resource);
+}
+
+static int
+bcmp_action_resource(register _Xconst void *string,
+ register _Xconst void *resource)
+{
+ return (strcmp((String)string,
+ XrmQuarkToString((*(XawActionRes **)resource)->qname)));
+}
+
+static XawActionRes *
+_XawFindActionRes(XawActionResList *list, Widget detail, String name)
+{
+ XawActionRes **res;
+
+ if (!list->resources)
+ return (NULL);
+
+ res = (XawActionRes **)bsearch(name, list->resources,
+ list->num_common_resources,
+ sizeof(XawActionRes*), bcmp_action_resource);
+
+ if (!res && XtParent(detail)
+ && XtIsSubclass(XtParent(detail), constraintWidgetClass))
+ {
+ XawActionResList *cons = XawGetActionResList(XtClass(XtParent(detail)));
+
+ if (cons)
+ res = (XawActionRes **)
+ bsearch(name, &cons->resources[cons->num_common_resources],
+ cons->num_constraint_resources,
+ sizeof(XawActionRes*), bcmp_action_resource);
+ }
+
+ return (res ? *res : NULL);
+}
+
+/*
+ * Start of Variables Implementation Code
+ */
+/* For speed, only does memory allocation when really required */
+static String
+_XawEscapeActionVarValue(String value)
+{
+ String escape;
+
+ if (value[0] == '$' || value[0] == '\\')
+ {
+ escape = XtMalloc(strlen(value) + 2);
+ escape[0] = '\\';
+ strcpy(escape + 1, value);
+ return (escape);
+ }
+ return (NULL);
+}
+
+/* For speed, only does memory allocation when really required */
+static String
+_XawUnescapeActionVarValue(String value)
+{
+ String unescape;
+
+ if (value[0] == '\\')
+ {
+ unescape = XtMalloc(strlen(value));
+ strcpy(unescape, value + 1);
+ return (unescape);
+ }
+ return (NULL);
+}
+
+static void
+XawDeclareActionVar(XawActionVarList *list, String name, String value)
+{
+ XawActionVar *variable;
+ String escape = NULL;
+
+ if (name[0] != XAW_PRIV_VAR_PREFIX)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg), "declare(): variable name must begin with "
+ "\'%c\', at %s = %s", XAW_PRIV_VAR_PREFIX, name, value);
+ XtAppWarning(XtWidgetToApplicationContext(list->widget), msg);
+ return;
+ }
+ variable = _XawFindActionVar(list, name);
+ if (!variable)
+ variable = _XawCreateActionVar(list, name);
+ if (value)
+ escape = _XawEscapeActionVarValue(value);
+
+ if (variable->qvalue)
+ {
+ String val = escape ? escape : value;
+
+ if (strcmp(XrmQuarkToString(variable->qvalue), val) == 0)
+ {
+ if (escape)
+ XtFree(escape);
+ return;
+ }
+ }
+ variable->qvalue = (escape ? XrmStringToQuark(escape) :
+ (value ? XrmStringToQuark(value) : NULLQUARK));
+ if (escape)
+ XtFree(escape);
+}
+
+static String
+XawConvertActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar *variable;
+ String unescape;
+ XrmQuark quark;
+
+ if (name[0] != XAW_PRIV_VAR_PREFIX)
+ return (name);
+
+ variable = _XawFindActionVar(list, name);
+ if (!variable || variable->qvalue == NULLQUARK)
+ return (name);
+ unescape = _XawUnescapeActionVarValue(XrmQuarkToString(variable->qvalue));
+ if (unescape)
+ {
+ quark = XrmStringToQuark(unescape);
+ XtFree(unescape);
+ }
+ else
+ quark = variable->qvalue;
+
+ return (XrmQuarkToString(quark));
+}
+
+XawActionVarList *
+XawGetActionVarList(Widget w)
+{
+ XawActionVarList *list;
+
+ list = _XawFindActionVarList(w);
+ if (!list)
+ list = _XawCreateActionVarList(w);
+
+ return (list);
+}
+
+static int
+qcmp_action_variable_list(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return ((char *)((*(XawActionVarList **)left)->widget) -
+ (char *)((*(XawActionVarList **)right)->widget));
+}
+
+static XawActionVarList *
+_XawCreateActionVarList(Widget w)
+{
+ XawActionVarList *list;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating action variable list for widget %s (%p)\n",
+ XtName(w), w);
+#endif
+
+ list = (XawActionVarList *)XtMalloc(sizeof(XawActionVarList));
+ list->widget = w;
+ list->num_variables = 0;
+ list->variables = NULL;
+
+ if (!variable_list)
+ {
+ num_variable_list = 1;
+ variable_list = (XawActionVarList **)XtMalloc(sizeof(XawActionVarList*));
+ variable_list[0] = list;
+ }
+ else
+ {
+ ++num_variable_list;
+ variable_list = (XawActionVarList **)
+ XtRealloc((char *)variable_list,
+ sizeof(XawActionVarList *) * num_variable_list);
+ variable_list[num_variable_list - 1] = list;
+ qsort(variable_list, num_variable_list, sizeof(XawActionVarList*),
+ qcmp_action_variable_list);
+ }
+
+ XtAddCallback(w, XtNdestroyCallback, _XawDestroyActionVarList,
+ (XtPointer)list);
+
+ return (list);
+}
+
+static int
+bcmp_action_variable_list(register _Xconst void *widget,
+ register _Xconst void *list)
+{
+ return ((char *)widget - (char *)((*(XawActionVarList **)list)->widget));
+}
+
+static XawActionVarList *
+_XawFindActionVarList(Widget w)
+{
+ XawActionVarList **list;
+
+ if (!num_variable_list)
+ return (NULL);
+
+ list = (XawActionVarList **)bsearch(w, variable_list, num_variable_list,
+ sizeof(XawActionVarList*),
+ bcmp_action_variable_list);
+
+ return (list ? *list : NULL);
+}
+
+static int
+qcmp_action_variable(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return (strcmp(XrmQuarkToString((*(XawActionVar **)left)->qname),
+ XrmQuarkToString((*(XawActionVar **)right)->qname)));
+}
+
+static XawActionVar *
+_XawCreateActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar *variable;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating action variable '%s' for widget %s (%p)\n",
+ name, XtName(list->widget), list->widget);
+#endif
+
+ variable = (XawActionVar *)XtMalloc(sizeof(XawActionVar));
+ variable->qname = XrmStringToQuark(name);
+ variable->qvalue = NULLQUARK;
+
+ if (!list->variables)
+ {
+ list->num_variables = 1;
+ list->variables = (XawActionVar **)XtMalloc(sizeof(XawActionVar*));
+ list->variables[0] = variable;
+ }
+ else
+ {
+ ++list->num_variables;
+ list->variables = (XawActionVar **)XtRealloc((char *)list->variables,
+ sizeof(XawActionVar *) *
+ list->num_variables);
+ list->variables[list->num_variables - 1] = variable;
+ qsort(list->variables, list->num_variables, sizeof(XawActionVar*),
+ qcmp_action_variable);
+ }
+ return (variable);
+}
+
+static int
+bcmp_action_variable(register _Xconst void *string,
+ register _Xconst void *variable)
+{
+ return (strcmp((String)string,
+ XrmQuarkToString((*(XawActionVar **)variable)->qname)));
+}
+
+static XawActionVar *
+_XawFindActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar **var;
+
+ if (!list->variables)
+ return (NULL);
+
+ var = (XawActionVar **)bsearch(name, list->variables, list->num_variables,
+ sizeof(XawActionVar*), bcmp_action_variable);
+
+ return (var ? *var : NULL);
+}
+
+/*ARGSUSED*/
+static void
+_XawDestroyActionVarList(Widget w, XtPointer client_data, XtPointer call_data)
+{
+ XawActionVarList *list = (XawActionVarList *)client_data;
+ Cardinal i;
+
+ for (i = 0; i < num_variable_list; i++)
+ if (variable_list[i] == list)
+ break;
+ if (i >= num_variable_list || list->widget != w
+ || variable_list[i]->widget != w)
+ {
+ XtWarning("destroy-variable-list(): Bad widget argument.");
+ return;
+ }
+ if (--num_variable_list > 0)
+ {
+ memmove(&variable_list[i], &variable_list[i + 1],
+ (num_variable_list - i) * sizeof(XawActionVarList *));
+ variable_list = (XawActionVarList **)
+ XtRealloc((char *)variable_list, sizeof(XawActionVarList *) *
+ num_variable_list);
+ }
+ else
+ {
+ XtFree((char *)variable_list);
+ variable_list = NULL;
+ }
+
+ XtFree((char *)list->variables);
+ XtFree((char *)list);
+}
+
+#endif /* OLDXAW */