diff options
Diffstat (limited to 'libXaw/src/Actions.c')
-rw-r--r-- | libXaw/src/Actions.c | 1139 |
1 files changed, 1139 insertions, 0 deletions
diff --git a/libXaw/src/Actions.c b/libXaw/src/Actions.c new file mode 100644 index 000000000..a65308b6a --- /dev/null +++ b/libXaw/src/Actions.c @@ -0,0 +1,1139 @@ +/* + * 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.17 2003/03/25 04:18:10 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#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" + +#ifdef __UNIXOS2__ +static char dummy; +#endif + +#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 = ¶ms[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); + + 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 */ |