1137 lines
27 KiB
C
1137 lines
27 KiB
C
/*
|
|
* 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.18 2004/01/23 03:57:58 dawes 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"
|
|
|
|
#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 */
|