Import xkbcomp sources for CompileKeymap
A copy of the xkbcomp sources (except the frontend) have been copied in to provide a means to compile a XkbDescPtr. This definitely doesn't build or do the right thing yet.master
parent
f4d8e2932c
commit
0c1bbb05d9
24
configure.ac
24
configure.ac
|
@ -29,6 +29,7 @@ AC_CONFIG_HEADERS([src/config.h])
|
|||
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_CC
|
||||
AC_PROG_YACC
|
||||
|
||||
m4_ifndef([PKG_PROG_PKG_CONFIG],
|
||||
[m4_fatal([Could not locate the pkg-config autoconf macros.
|
||||
|
@ -38,6 +39,11 @@ m4_ifndef([PKG_PROG_PKG_CONFIG],
|
|||
autoreconf/autogen.sh.])])
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
# Require xorg-macros version 1.2.0 or newer for XORG_CHANGELOG macro
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
[m4_fatal([must install xorg-macros before running autoconf/autogen.sh])])
|
||||
XORG_MACROS_VERSION([1.2.0])
|
||||
|
||||
dnl Build native compiler needed for makekeys
|
||||
AC_ARG_VAR([CC_FOR_BUILD], [Build native C compiler program])
|
||||
if test "x$CC_FOR_BUILD" = x; then
|
||||
|
@ -48,6 +54,10 @@ if test "x$CC_FOR_BUILD" = x; then
|
|||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS([strdup strcasecmp])
|
||||
XORG_CHECK_MALLOC_ZERO
|
||||
XORG_CWARNFLAGS
|
||||
|
||||
PKG_CHECK_MODULES([X11], [xproto kbproto >= 1.0.99.1])
|
||||
|
||||
dnl Ensure we have keysym headers
|
||||
|
@ -69,13 +79,14 @@ AC_SUBST([XF86KEYSYM_H])
|
|||
|
||||
AC_SUBST([KS_HEADERS], ['$(KEYSYMDEF_H) $(XF86KEYSYM_H)'])
|
||||
|
||||
# Require xorg-macros version 1.2.0 or newer for XORG_CHANGELOG macro
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
[m4_fatal([must install xorg-macros before running autoconf/autogen.sh])])
|
||||
XORG_MACROS_VERSION([1.2.0])
|
||||
AC_ARG_WITH([xkb_config_root],
|
||||
[AC_HELP_STRING([--with-xkb-config-root=<paths>],
|
||||
[Set default XKB config root (default: ${datadir}/X11/xkb)])],
|
||||
[XKBCONFIGROOT="$withval"],
|
||||
[XKBCONFIGROOT='${datadir}/X11/xkb'])
|
||||
AC_SUBST([XKBCONFIGROOT])
|
||||
|
||||
XORG_RELEASE_VERSION
|
||||
XORG_CHECK_MALLOC_ZERO
|
||||
XORG_CWARNFLAGS
|
||||
XORG_CHANGELOG
|
||||
|
||||
AC_OUTPUT([
|
||||
|
@ -83,5 +94,6 @@ Makefile
|
|||
include/Makefile
|
||||
src/Makefile
|
||||
src/makekeys/Makefile
|
||||
src/xkbcomp/Makefile
|
||||
test/Makefile
|
||||
])
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
SUBDIRS = makekeys
|
||||
SUBDIRS = makekeys xkbcomp
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(builddir)/makekeys
|
||||
AM_CFLAGS = $(X11_CFLAGS) $(CWARNFLAGS) $(XMALLOC_ZERO_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libxkbcommon.la
|
||||
libxkbcommon_la_LIBADD = xkbcomp/libxkbcomp.la
|
||||
libxkbcommon_la_SOURCES = \
|
||||
XKBcommonint.h \
|
||||
alloc.c \
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src
|
||||
AM_CFLAGS = $(X11_CFLAGS) $(CWARNFLAGS) \
|
||||
-DDFLT_XKB_CONFIG_ROOT='"$(XKBCONFIGROOT)"'
|
||||
|
||||
BUILT_SOURCES = xkbparse.c
|
||||
MAINTAINERCLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
noinst_LTLIBRARIES = libxkbcomp.la
|
||||
libxkbcomp_la_SOURCES = \
|
||||
action.c \
|
||||
action.h \
|
||||
alias.c \
|
||||
alias.h \
|
||||
compat.c \
|
||||
compat.h \
|
||||
expr.c \
|
||||
expr.h \
|
||||
geometry.c \
|
||||
indicators.c \
|
||||
indicators.h \
|
||||
keycodes.c \
|
||||
keycodes.h \
|
||||
keymap.c \
|
||||
keytypes.c \
|
||||
listing.c \
|
||||
misc.c \
|
||||
misc.h \
|
||||
parseutils.c \
|
||||
parseutils.h \
|
||||
symbols.c \
|
||||
tokens.h \
|
||||
utils.c \
|
||||
utils.h \
|
||||
vmod.c \
|
||||
vmod.h \
|
||||
xkbcomp.h \
|
||||
xkbparse.y \
|
||||
xkbpath.c \
|
||||
xkbpath.h \
|
||||
xkbscan.c
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef ACTION_H
|
||||
#define ACTION_H 1
|
||||
|
||||
#define F_ClearLocks 0
|
||||
#define F_LatchToLock 1
|
||||
#define F_GenKeyEvent 2
|
||||
#define F_Report 3
|
||||
#define F_Default 4
|
||||
#define F_Affect 5
|
||||
#define F_Increment 6
|
||||
#define F_Modifiers 7
|
||||
#define F_Group 8
|
||||
#define F_X 9
|
||||
#define F_Y 10
|
||||
#define F_Accel 11
|
||||
#define F_Button 12
|
||||
#define F_Value 13
|
||||
#define F_Controls 14
|
||||
#define F_Type 15
|
||||
#define F_Count 16
|
||||
#define F_Screen 17
|
||||
#define F_Same 18
|
||||
#define F_Data 19
|
||||
#define F_Device 20
|
||||
#define F_Keycode 21
|
||||
#define F_ModsToClear 22
|
||||
#define F_LastField F_ModsToClear
|
||||
#define F_NumFields (F_LastField+1)
|
||||
|
||||
#define PrivateAction (XkbSA_LastAction+1)
|
||||
|
||||
typedef struct _ActionInfo
|
||||
{
|
||||
unsigned action;
|
||||
unsigned field;
|
||||
ExprDef *array_ndx;
|
||||
ExprDef *value;
|
||||
struct _ActionInfo *next;
|
||||
} ActionInfo;
|
||||
|
||||
extern int HandleActionDef(ExprDef * /* def */ ,
|
||||
XkbDescPtr /* xkb */ ,
|
||||
XkbAnyAction * /* action */ ,
|
||||
unsigned /* mergeMode */ ,
|
||||
ActionInfo * /* info */
|
||||
);
|
||||
|
||||
extern int SetActionField(XkbDescPtr /* xkb */ ,
|
||||
char * /* elem */ ,
|
||||
char * /* field */ ,
|
||||
ExprDef * /* index */ ,
|
||||
ExprDef * /* value */ ,
|
||||
ActionInfo ** /* info_rtrn */
|
||||
);
|
||||
|
||||
extern void ActionsInit(void);
|
||||
|
||||
extern LookupEntry ctrlNames[];
|
||||
|
||||
#endif /* ACTION_H */
|
|
@ -0,0 +1,289 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "misc.h"
|
||||
#include "alias.h"
|
||||
#include "keycodes.h"
|
||||
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
|
||||
static void
|
||||
HandleCollision(AliasInfo * old, AliasInfo * new)
|
||||
{
|
||||
if (strncmp(new->real, old->real, XkbKeyNameLength) == 0)
|
||||
{
|
||||
if (((new->def.fileID == old->def.fileID) && (warningLevel > 0)) ||
|
||||
(warningLevel > 9))
|
||||
{
|
||||
WARN2("Alias of %s for %s declared more than once\n",
|
||||
XkbKeyNameText(new->alias, XkbMessage),
|
||||
XkbKeyNameText(new->real, XkbMessage));
|
||||
ACTION("First definition ignored\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *use, *ignore;
|
||||
if (new->def.merge == MergeAugment)
|
||||
{
|
||||
use = old->real;
|
||||
ignore = new->real;
|
||||
}
|
||||
else
|
||||
{
|
||||
use = new->real;
|
||||
ignore = old->real;
|
||||
}
|
||||
if (((old->def.fileID == new->def.fileID) && (warningLevel > 0)) ||
|
||||
(warningLevel > 9))
|
||||
{
|
||||
WARN1("Multiple definitions for alias %s\n",
|
||||
XkbKeyNameText(old->alias, XkbMessage));
|
||||
ACTION2("Using %s, ignoring %s\n",
|
||||
XkbKeyNameText(use, XkbMessage),
|
||||
XkbKeyNameText(ignore, XkbMessage));
|
||||
}
|
||||
if (use != old->real)
|
||||
memcpy(old->real, use, XkbKeyNameLength);
|
||||
}
|
||||
old->def.fileID = new->def.fileID;
|
||||
old->def.merge = new->def.merge;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
InitAliasInfo(AliasInfo * info,
|
||||
unsigned merge, unsigned file_id, char *alias, char *real)
|
||||
{
|
||||
bzero(info, sizeof(AliasInfo));
|
||||
info->def.merge = merge;
|
||||
info->def.fileID = file_id;
|
||||
strncpy(info->alias, alias, XkbKeyNameLength);
|
||||
strncpy(info->real, real, XkbKeyNameLength);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
HandleAliasDef(KeyAliasDef * def,
|
||||
unsigned merge, unsigned file_id, AliasInfo ** info_in)
|
||||
{
|
||||
AliasInfo *info;
|
||||
|
||||
for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next)
|
||||
{
|
||||
if (strncmp(info->alias, def->alias, XkbKeyNameLength) == 0)
|
||||
{
|
||||
AliasInfo new;
|
||||
InitAliasInfo(&new, merge, file_id, def->alias, def->real);
|
||||
HandleCollision(info, &new);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
info = uTypedCalloc(1, AliasInfo);
|
||||
if (info == NULL)
|
||||
{
|
||||
WSGO("Allocation failure in HandleAliasDef\n");
|
||||
return False;
|
||||
}
|
||||
info->def.fileID = file_id;
|
||||
info->def.merge = merge;
|
||||
info->def.next = (CommonInfo *) * info_in;
|
||||
memcpy(info->alias, def->alias, XkbKeyNameLength);
|
||||
memcpy(info->real, def->real, XkbKeyNameLength);
|
||||
*info_in = (AliasInfo *) AddCommonInfo(&(*info_in)->def, &info->def);
|
||||
return True;
|
||||
}
|
||||
|
||||
void
|
||||
ClearAliases(AliasInfo ** info_in)
|
||||
{
|
||||
if ((info_in) && (*info_in))
|
||||
ClearCommonInfo(&(*info_in)->def);
|
||||
return;
|
||||
}
|
||||
|
||||
Bool
|
||||
MergeAliases(AliasInfo ** into, AliasInfo ** merge, unsigned how_merge)
|
||||
{
|
||||
AliasInfo *tmp;
|
||||
KeyAliasDef def;
|
||||
|
||||
if ((*merge) == NULL)
|
||||
return True;
|
||||
if ((*into) == NULL)
|
||||
{
|
||||
*into = *merge;
|
||||
*merge = NULL;
|
||||
return True;
|
||||
}
|
||||
bzero((char *) &def, sizeof(KeyAliasDef));
|
||||
for (tmp = *merge; tmp != NULL; tmp = (AliasInfo *) tmp->def.next)
|
||||
{
|
||||
if (how_merge == MergeDefault)
|
||||
def.merge = tmp->def.merge;
|
||||
else
|
||||
def.merge = how_merge;
|
||||
memcpy(def.alias, tmp->alias, XkbKeyNameLength);
|
||||
memcpy(def.real, tmp->real, XkbKeyNameLength);
|
||||
if (!HandleAliasDef(&def, def.merge, tmp->def.fileID, into))
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
int
|
||||
ApplyAliases(XkbDescPtr xkb, Bool toGeom, AliasInfo ** info_in)
|
||||
{
|
||||
register int i;
|
||||
XkbKeyAliasPtr old, a;
|
||||
AliasInfo *info;
|
||||
int nNew, nOld;
|
||||
Status status;
|
||||
|
||||
if (*info_in == NULL)
|
||||
return True;
|
||||
if (toGeom)
|
||||
{
|
||||
nOld = (xkb->geom ? xkb->geom->num_key_aliases : 0);
|
||||
old = (xkb->geom ? xkb->geom->key_aliases : NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
nOld = (xkb->names ? xkb->names->num_key_aliases : 0);
|
||||
old = (xkb->names ? xkb->names->key_aliases : NULL);
|
||||
}
|
||||
for (nNew = 0, info = *info_in; info != NULL;
|
||||
info = (AliasInfo *) info->def.next)
|
||||
{
|
||||
unsigned long lname;
|
||||
unsigned int kc;
|
||||
|
||||
lname = KeyNameToLong(info->real);
|
||||
if (!FindNamedKey(xkb, lname, &kc, False, CreateKeyNames(xkb), 0))
|
||||
{
|
||||
if (warningLevel > 4)
|
||||
{
|
||||
WARN2("Attempt to alias %s to non-existent key %s\n",
|
||||
XkbKeyNameText(info->alias, XkbMessage),
|
||||
XkbKeyNameText(info->real, XkbMessage));
|
||||
ACTION("Ignored\n");
|
||||
}
|
||||
info->alias[0] = '\0';
|
||||
continue;
|
||||
}
|
||||
lname = KeyNameToLong(info->alias);
|
||||
if (FindNamedKey(xkb, lname, &kc, False, False, 0))
|
||||
{
|
||||
if (warningLevel > 4)
|
||||
{
|
||||
WARN("Attempt to create alias with the name of a real key\n");
|
||||
ACTION2("Alias \"%s = %s\" ignored\n",
|
||||
XkbKeyNameText(info->alias, XkbMessage),
|
||||
XkbKeyNameText(info->real, XkbMessage));
|
||||
}
|
||||
info->alias[0] = '\0';
|
||||
continue;
|
||||
}
|
||||
nNew++;
|
||||
if (old)
|
||||
{
|
||||
for (i = 0, a = old; i < nOld; i++, a++)
|
||||
{
|
||||
if (strncmp(a->alias, info->alias, XkbKeyNameLength) == 0)
|
||||
{
|
||||
AliasInfo old;
|
||||
InitAliasInfo(&old, MergeAugment, 0, a->alias, a->real);
|
||||
HandleCollision(&old, info);
|
||||
memcpy(old.real, a->real, XkbKeyNameLength);
|
||||
info->alias[0] = '\0';
|
||||
nNew--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nNew == 0)
|
||||
{
|
||||
ClearCommonInfo(&(*info_in)->def);
|
||||
*info_in = NULL;
|
||||
return True;
|
||||
}
|
||||
status = Success;
|
||||
if (toGeom)
|
||||
{
|
||||
if (!xkb->geom)
|
||||
{
|
||||
XkbGeometrySizesRec sizes;
|
||||
bzero((char *) &sizes, sizeof(XkbGeometrySizesRec));
|
||||
sizes.which = XkbGeomKeyAliasesMask;
|
||||
sizes.num_key_aliases = nOld + nNew;
|
||||
status = XkbAllocGeometry(xkb, &sizes);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = XkbAllocGeomKeyAliases(xkb->geom, nOld + nNew);
|
||||
}
|
||||
if (xkb->geom)
|
||||
old = xkb->geom->key_aliases;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = XkbAllocNames(xkb, XkbKeyAliasesMask, 0, nOld + nNew);
|
||||
if (xkb->names)
|
||||
old = xkb->names->key_aliases;
|
||||
}
|
||||
if (status != Success)
|
||||
{
|
||||
WSGO("Allocation failure in ApplyAliases\n");
|
||||
return False;
|
||||
}
|
||||
if (toGeom)
|
||||
a = &xkb->geom->key_aliases[nOld];
|
||||
else
|
||||
a = &xkb->names->key_aliases[nOld];
|
||||
for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next)
|
||||
{
|
||||
if (info->alias[0] != '\0')
|
||||
{
|
||||
strncpy(a->alias, info->alias, XkbKeyNameLength);
|
||||
strncpy(a->real, info->real, XkbKeyNameLength);
|
||||
a++;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if ((a - old) != (nOld + nNew))
|
||||
{
|
||||
WSGO2("Expected %d aliases total but created %d\n", nOld + nNew,
|
||||
a - old);
|
||||
}
|
||||
#endif
|
||||
if (toGeom)
|
||||
xkb->geom->num_key_aliases += nNew;
|
||||
ClearCommonInfo(&(*info_in)->def);
|
||||
*info_in = NULL;
|
||||
return True;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef ALIAS_H
|
||||
#define ALIAS_H 1
|
||||
|
||||
typedef struct _AliasInfo
|
||||
{
|
||||
CommonInfo def;
|
||||
char alias[XkbKeyNameLength + 1];
|
||||
char real[XkbKeyNameLength + 1];
|
||||
} AliasInfo;
|
||||
|
||||
extern int HandleAliasDef(KeyAliasDef * /* def */ ,
|
||||
unsigned /* merge */ ,
|
||||
unsigned /* file_id */ ,
|
||||
AliasInfo ** /* info */
|
||||
);
|
||||
|
||||
extern void ClearAliases(AliasInfo ** /* info */
|
||||
);
|
||||
|
||||
extern Bool MergeAliases(AliasInfo ** /* into */ ,
|
||||
AliasInfo ** /* merge */ ,
|
||||
unsigned /* how_merge */
|
||||
);
|
||||
|
||||
extern int ApplyAliases(XkbDescPtr /* xkb */ ,
|
||||
Bool /* toGeom */ ,
|
||||
AliasInfo ** /* info */
|
||||
);
|
||||
|
||||
#endif /* ALIAS_H */
|
|
@ -0,0 +1,880 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include <X11/Xos.h>
|
||||
#include "xkbcomp.h"
|
||||
#include "tokens.h"
|
||||
#include "expr.h"
|
||||
#include "vmod.h"
|
||||
#include "misc.h"
|
||||
#include "indicators.h"
|
||||
#include "action.h"
|
||||
#include "compat.h"
|
||||
|
||||
typedef struct _SymInterpInfo
|
||||
{
|
||||
CommonInfo defs;
|
||||
XkbSymInterpretRec interp;
|
||||
} SymInterpInfo;
|
||||
|
||||
#define _SI_VirtualMod (1<<0)
|
||||
#define _SI_Action (1<<1)
|
||||
#define _SI_AutoRepeat (1<<2)
|
||||
#define _SI_LockingKey (1<<3)
|
||||
#define _SI_LevelOneOnly (1<<4)
|
||||
|
||||
typedef struct _GroupCompatInfo
|
||||
{
|
||||
unsigned char fileID;
|
||||
unsigned char merge;
|
||||
unsigned char real_mods;
|
||||
unsigned short vmods;
|
||||
} GroupCompatInfo;
|
||||
|
||||
typedef struct _CompatInfo
|
||||
{
|
||||
char *name;
|
||||
unsigned fileID;
|
||||
int errorCount;
|
||||
int nInterps;
|
||||
SymInterpInfo *interps;
|
||||
SymInterpInfo dflt;
|
||||
LEDInfo ledDflt;
|
||||
GroupCompatInfo groupCompat[XkbNumKbdGroups];
|
||||
LEDInfo *leds;
|
||||
VModInfo vmods;
|
||||
ActionInfo *act;
|
||||
XkbDescPtr xkb;
|
||||
} CompatInfo;
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#define ReportSINotArray(si,f,i) \
|
||||
ReportNotArray("symbol interpretation",(f),siText((si),(i)))
|
||||
#define ReportSIBadType(si,f,w,i) \
|
||||
ReportBadType("symbol interpretation",(f),siText((si),(i)),(w))
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static char *
|
||||
siText(SymInterpInfo * si, CompatInfo * info)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
if (si == &info->dflt)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "default");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s+%s(%s)",
|
||||
XkbKeysymText(si->interp.sym, XkbMessage),
|
||||
XkbSIMatchText(si->interp.match, XkbMessage),
|
||||
XkbModMaskText(si->interp.mods, XkbMessage));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
InitCompatInfo(CompatInfo * info, XkbDescPtr xkb)
|
||||
{
|
||||
register int i;
|
||||
|
||||
info->xkb = xkb;
|
||||
info->name = NULL;
|
||||
info->fileID = 0;
|
||||
info->errorCount = 0;
|
||||
info->nInterps = 0;
|
||||
info->interps = NULL;
|
||||
info->act = NULL;
|
||||
info->dflt.defs.fileID = info->fileID;
|
||||
info->dflt.defs.defined = 0;
|
||||
info->dflt.defs.merge = MergeOverride;
|
||||
info->dflt.interp.flags = 0;
|
||||
info->dflt.interp.virtual_mod = XkbNoModifier;
|
||||
info->dflt.interp.act.type = XkbSA_NoAction;
|
||||
for (i = 0; i < XkbAnyActionDataSize; i++)
|
||||
{
|
||||
info->dflt.interp.act.data[i] = 0;
|
||||
}
|
||||
ClearIndicatorMapInfo(xkb->dpy, &info->ledDflt);
|
||||
info->ledDflt.defs.fileID = info->fileID;
|
||||
info->ledDflt.defs.defined = 0;
|
||||
info->ledDflt.defs.merge = MergeOverride;
|
||||
bzero((char *) &info->groupCompat[0],
|
||||
XkbNumKbdGroups * sizeof(GroupCompatInfo));
|
||||
info->leds = NULL;
|
||||
InitVModInfo(&info->vmods, xkb);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearCompatInfo(CompatInfo * info, XkbDescPtr xkb)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (info->name != NULL)
|
||||
uFree(info->name);
|
||||
info->name = NULL;
|
||||
info->dflt.defs.defined = 0;
|
||||
info->dflt.defs.merge = MergeAugment;
|
||||
info->dflt.interp.flags = 0;
|
||||
info->dflt.interp.virtual_mod = XkbNoModifier;
|
||||
info->dflt.interp.act.type = XkbSA_NoAction;
|
||||
for (i = 0; i < XkbAnyActionDataSize; i++)
|
||||
{
|
||||
info->dflt.interp.act.data[i] = 0;
|
||||
}
|
||||
ClearIndicatorMapInfo(xkb->dpy, &info->ledDflt);
|
||||
info->nInterps = 0;
|
||||
info->interps = (SymInterpInfo *) ClearCommonInfo(&info->interps->defs);
|
||||
bzero((char *) &info->groupCompat[0],
|
||||
XkbNumKbdGroups * sizeof(GroupCompatInfo));
|
||||
info->leds = (LEDInfo *) ClearCommonInfo(&info->leds->defs);
|
||||
/* 3/30/94 (ef) -- XXX! Should free action info here */
|
||||
ClearVModInfo(&info->vmods, xkb);
|
||||
return;
|
||||
}
|
||||
|
||||
static SymInterpInfo *
|
||||
NextInterp(CompatInfo * info)
|
||||
{
|
||||
SymInterpInfo *si;
|
||||
|
||||
si = uTypedAlloc(SymInterpInfo);
|
||||
if (si)
|
||||
{
|
||||
bzero((char *) si, sizeof(SymInterpInfo));
|
||||
info->interps =
|
||||
(SymInterpInfo *) AddCommonInfo(&info->interps->defs,
|
||||
(CommonInfo *) si);
|
||||
info->nInterps++;
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
static SymInterpInfo *
|
||||
FindMatchingInterp(CompatInfo * info, SymInterpInfo * new)
|
||||
{
|
||||
SymInterpInfo *old;
|
||||
|
||||
for (old = info->interps; old != NULL;
|
||||
old = (SymInterpInfo *) old->defs.next)
|
||||
{
|
||||
if ((old->interp.sym == new->interp.sym) &&
|
||||
(old->interp.mods == new->interp.mods) &&
|
||||
(old->interp.match == new->interp.match))
|
||||
{
|
||||
return old;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Bool
|
||||
AddInterp(CompatInfo * info, SymInterpInfo * new)
|
||||
{
|
||||
unsigned collide;
|
||||
SymInterpInfo *old;
|
||||
|
||||
collide = 0;
|
||||
old = FindMatchingInterp(info, new);
|
||||
if (old != NULL)
|
||||
{
|
||||
if (new->defs.merge == MergeReplace)
|
||||
{
|
||||
SymInterpInfo *next = (SymInterpInfo *) old->defs.next;
|
||||
if (((old->defs.fileID == new->defs.fileID)
|
||||
&& (warningLevel > 0)) || (warningLevel > 9))
|
||||
{
|
||||
WARN1("Multiple definitions for \"%s\"\n", siText(new, info));
|
||||
ACTION("Earlier interpretation ignored\n");
|
||||
}
|
||||
*old = *new;
|
||||
old->defs.next = &next->defs;
|
||||
return True;
|
||||
}
|
||||
if (UseNewField(_SI_VirtualMod, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->interp.virtual_mod = new->interp.virtual_mod;
|
||||
old->defs.defined |= _SI_VirtualMod;
|
||||
}
|
||||
if (UseNewField(_SI_Action, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->interp.act = new->interp.act;
|
||||
old->defs.defined |= _SI_Action;
|
||||
}
|
||||
if (UseNewField(_SI_AutoRepeat, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->interp.flags &= ~XkbSI_AutoRepeat;
|
||||
old->interp.flags |= (new->interp.flags & XkbSI_AutoRepeat);
|
||||
old->defs.defined |= _SI_AutoRepeat;
|
||||
}
|
||||
if (UseNewField(_SI_LockingKey, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->interp.flags &= ~XkbSI_LockingKey;
|
||||
old->interp.flags |= (new->interp.flags & XkbSI_LockingKey);
|
||||
old->defs.defined |= _SI_LockingKey;
|
||||
}
|
||||
if (UseNewField(_SI_LevelOneOnly, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->interp.match &= ~XkbSI_LevelOneOnly;
|
||||
old->interp.match |= (new->interp.match & XkbSI_LevelOneOnly);
|
||||
old->defs.defined |= _SI_LevelOneOnly;
|
||||
}
|
||||
if (collide)
|
||||
{
|
||||
WARN1("Multiple interpretations of \"%s\"\n", siText(new, info));
|
||||
ACTION1("Using %s definition for duplicate fields\n",
|
||||
(new->defs.merge != MergeAugment ? "last" : "first"));
|
||||
}
|
||||
return True;
|
||||
}
|
||||
old = new;
|
||||
if ((new = NextInterp(info)) == NULL)
|
||||
return False;
|
||||
*new = *old;
|
||||
new->defs.next = NULL;
|
||||
return True;
|
||||
}
|
||||
|
||||
static Bool
|
||||
AddGroupCompat(CompatInfo * info, unsigned group, GroupCompatInfo * newGC)
|
||||
{
|
||||
GroupCompatInfo *gc;
|
||||
unsigned merge;
|
||||
|
||||
merge = newGC->merge;
|
||||
gc = &info->groupCompat[group];
|
||||
if (((gc->real_mods == newGC->real_mods) && (gc->vmods == newGC->vmods)))
|
||||
{
|
||||
return True;
|
||||
}
|
||||
if (((gc->fileID == newGC->fileID) && (warningLevel > 0))
|
||||
|| (warningLevel > 9))
|
||||
{
|
||||
WARN1("Compat map for group %d redefined\n", group + 1);
|
||||
ACTION1("Using %s definition\n",
|
||||
(merge == MergeAugment ? "old" : "new"));
|
||||
}
|
||||
if (merge != MergeAugment)
|
||||
*gc = *newGC;
|
||||
return True;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static Bool
|
||||
ResolveStateAndPredicate(ExprDef * expr,
|
||||
unsigned *pred_rtrn,
|
||||
unsigned *mods_rtrn, CompatInfo * info)
|
||||
{
|
||||
ExprResult result;
|
||||
|
||||
if (expr == NULL)
|
||||
{
|
||||
*pred_rtrn = XkbSI_AnyOfOrNone;
|
||||
*mods_rtrn = ~0;
|
||||
return True;
|
||||
}
|
||||
|
||||
*pred_rtrn = XkbSI_Exactly;
|
||||
if (expr->op == ExprActionDecl)
|
||||
{
|
||||
char *pred_txt =
|
||||
XkbAtomText(NULL, expr->value.action.name, XkbMessage);
|
||||
if (uStrCaseCmp(pred_txt, "noneof") == 0)
|
||||
*pred_rtrn = XkbSI_NoneOf;
|
||||
else if (uStrCaseCmp(pred_txt, "anyofornone") == 0)
|
||||
*pred_rtrn = XkbSI_AnyOfOrNone;
|
||||
else if (uStrCaseCmp(pred_txt, "anyof") == 0)
|
||||
*pred_rtrn = XkbSI_AnyOf;
|
||||
else if (uStrCaseCmp(pred_txt, "allof") == 0)
|
||||
*pred_rtrn = XkbSI_AllOf;
|
||||
else if (uStrCaseCmp(pred_txt, "exactly") == 0)
|
||||
*pred_rtrn = XkbSI_Exactly;
|
||||
else
|
||||
{
|
||||
ERROR1("Illegal modifier predicate \"%s\"\n", pred_txt);
|
||||
ACTION("Ignored\n");
|
||||
return False;
|
||||
}
|
||||
expr = expr->value.action.args;
|
||||
}
|
||||
else if (expr->op == ExprIdent)
|
||||
{
|
||||
char *pred_txt = XkbAtomText(NULL, expr->value.str, XkbMessage);
|
||||
if ((pred_txt) && (uStrCaseCmp(pred_txt, "any") == 0))
|
||||
{
|
||||
*pred_rtrn = XkbSI_AnyOf;
|
||||
*mods_rtrn = 0xff;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
if (ExprResolveModMask(expr, &result, NULL, NULL))
|
||||
{
|
||||
*mods_rtrn = result.uval;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
MergeIncludedCompatMaps(CompatInfo * into, CompatInfo * from, unsigned merge)
|
||||
{
|
||||
SymInterpInfo *si;
|
||||
LEDInfo *led, *rtrn, *next;
|
||||
GroupCompatInfo *gcm;
|
||||
register int i;
|
||||
|
||||
if (from->errorCount > 0)
|
||||
{
|
||||
into->errorCount += from->errorCount;
|
||||
return;
|
||||
}
|
||||
if (into->name == NULL)
|
||||
{
|
||||
into->name = from->name;
|
||||
from->name = NULL;
|
||||
}
|
||||
for (si = from->interps; si; si = (SymInterpInfo *) si->defs.next)
|
||||
{
|
||||
if (merge != MergeDefault)
|
||||
si->defs.merge = merge;
|
||||
if (!AddInterp(into, si))
|
||||
into->errorCount++;
|
||||
}
|
||||
for (i = 0, gcm = &from->groupCompat[0]; i < XkbNumKbdGroups; i++, gcm++)
|
||||
{
|
||||
if (merge != MergeDefault)
|
||||
gcm->merge = merge;
|
||||
if (!AddGroupCompat(into, i, gcm))
|
||||
into->errorCount++;
|
||||
}
|
||||
for (led = from->leds; led != NULL; led = next)
|
||||
{
|
||||
next = (LEDInfo *) led->defs.next;
|
||||
if (merge != MergeDefault)
|
||||
led->defs.merge = merge;
|
||||
rtrn = AddIndicatorMap(into->leds, led);
|
||||
if (rtrn != NULL)
|
||||
into->leds = rtrn;
|
||||
else
|
||||
into->errorCount++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
|
||||
XkbDescPtr /* xkb */ ,
|
||||
unsigned /* merge */ ,
|
||||
CompatInfo * /* info */
|
||||
);
|
||||
|
||||
static Bool
|
||||
HandleIncludeCompatMap(IncludeStmt * stmt,
|
||||
XkbDescPtr xkb, CompatInfo * info, FileHandler hndlr)
|
||||
{
|
||||
unsigned newMerge;
|
||||
XkbFile *rtrn;
|
||||
CompatInfo included;
|
||||
Bool haveSelf;
|
||||
|
||||
haveSelf = False;
|
||||
if ((stmt->file == NULL) && (stmt->map == NULL))
|
||||
{
|
||||
haveSelf = True;
|
||||
included = *info;
|
||||
bzero(info, sizeof(CompatInfo));
|
||||
}
|
||||
else if (ProcessIncludeFile(stmt, XkmCompatMapIndex, &rtrn, &newMerge))
|
||||
{
|
||||
InitCompatInfo(&included, xkb);
|
||||
included.fileID = rtrn->id;
|
||||
included.dflt = info->dflt;
|
||||
included.dflt.defs.fileID = rtrn->id;
|
||||
included.dflt.defs.merge = newMerge;
|
||||
included.ledDflt.defs.fileID = rtrn->id;
|
||||
included.ledDflt.defs.merge = newMerge;
|
||||
included.act = info->act;
|
||||
(*hndlr) (rtrn, xkb, MergeOverride, &included);
|
||||
if (stmt->stmt != NULL)
|
||||
{
|
||||
if (included.name != NULL)
|
||||
uFree(included.name);
|
||||
included.name = stmt->stmt;
|
||||
stmt->stmt = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->errorCount += 10;
|
||||
return False;
|
||||
}
|
||||
if ((stmt->next != NULL) && (included.errorCount < 1))
|
||||
{
|
||||
IncludeStmt *next;
|
||||
unsigned op;
|
||||
CompatInfo next_incl;
|
||||
|
||||
for (next = stmt->next; next != NULL; next = next->next)
|
||||
{
|
||||
if ((next->file == NULL) && (next->map == NULL))
|
||||
{
|
||||
haveSelf = True;
|
||||
MergeIncludedCompatMaps(&included, info, next->merge);
|
||||
ClearCompatInfo(info, xkb);
|
||||
}
|
||||
else if (ProcessIncludeFile(next, XkmCompatMapIndex, &rtrn, &op))
|
||||
{
|
||||
InitCompatInfo(&next_incl, xkb);
|
||||
next_incl.fileID = rtrn->id;
|
||||
next_incl.dflt = info->dflt;
|
||||
next_incl.dflt.defs.fileID = rtrn->id;
|
||||
next_incl.dflt.defs.merge = op;
|
||||
next_incl.ledDflt.defs.fileID = rtrn->id;
|
||||
next_incl.ledDflt.defs.merge = op;
|
||||
next_incl.act = info->act;
|
||||
(*hndlr) (rtrn, xkb, MergeOverride, &next_incl);
|
||||
MergeIncludedCompatMaps(&included, &next_incl, op);
|
||||
ClearCompatInfo(&next_incl, xkb);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->errorCount += 10;
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haveSelf)
|
||||
*info = included;
|
||||
else
|
||||
{
|
||||
MergeIncludedCompatMaps(info, &included, newMerge);
|
||||
ClearCompatInfo(&included, xkb);
|
||||
}
|
||||
return (info->errorCount == 0);
|
||||
}
|
||||
|
||||
static LookupEntry useModMapValues[] = {
|
||||
{"levelone", 1},
|
||||
{"level1", 1},
|
||||
{"anylevel", 0},
|
||||
{"any", 0},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
SetInterpField(SymInterpInfo * si,
|
||||
XkbDescPtr xkb,
|
||||
char *field,
|
||||
ExprDef * arrayNdx, ExprDef * value, CompatInfo * info)
|
||||
{
|
||||
int ok = 1;
|
||||
ExprResult tmp;
|
||||
|
||||
if (uStrCaseCmp(field, "action") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportSINotArray(si, field, info);
|
||||
ok = HandleActionDef(value, xkb, &si->interp.act, si->defs.merge,
|
||||
info->act);
|
||||
if (ok)
|
||||
si->defs.defined |= _SI_Action;
|
||||
}
|
||||
else if ((uStrCaseCmp(field, "virtualmodifier") == 0) ||
|
||||
(uStrCaseCmp(field, "virtualmod") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportSINotArray(si, field, info);
|
||||
ok = ResolveVirtualModifier(value, &tmp, &info->vmods);
|
||||
if (ok)
|
||||
{
|
||||
si->interp.virtual_mod = tmp.uval;
|
||||
si->defs.defined |= _SI_VirtualMod;
|
||||
}
|
||||
else
|
||||
return ReportSIBadType(si, field, "virtual modifier", info);
|
||||
}
|
||||
else if (uStrCaseCmp(field, "repeat") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportSINotArray(si, field, info);
|
||||
ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
|
||||
if (ok)
|
||||
{
|
||||
if (tmp.uval)
|
||||
si->interp.flags |= XkbSI_AutoRepeat;
|
||||
else
|
||||
si->interp.flags &= ~XkbSI_AutoRepeat;
|
||||
si->defs.defined |= _SI_AutoRepeat;
|
||||
}
|
||||
else
|
||||
return ReportSIBadType(si, field, "boolean", info);
|
||||
}
|
||||
else if (uStrCaseCmp(field, "locking") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportSINotArray(si, field, info);
|
||||
ok = ExprResolveBoolean(value, &tmp, NULL, NULL);
|
||||
if (ok)
|
||||
{
|
||||
if (tmp.uval)
|
||||
si->interp.flags |= XkbSI_LockingKey;
|
||||
else
|
||||
si->interp.flags &= ~XkbSI_LockingKey;
|
||||
si->defs.defined |= _SI_LockingKey;
|
||||
}
|
||||
else
|
||||
return ReportSIBadType(si, field, "boolean", info);
|
||||
}
|
||||
else if ((uStrCaseCmp(field, "usemodmap") == 0) ||
|
||||
(uStrCaseCmp(field, "usemodmapmods") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportSINotArray(si, field, info);
|
||||
ok = ExprResolveEnum(value, &tmp, useModMapValues);
|
||||
if (ok)
|
||||
{
|
||||
if (tmp.uval)
|
||||
si->interp.match |= XkbSI_LevelOneOnly;
|
||||
else
|
||||
si->interp.match &= ~XkbSI_LevelOneOnly;
|
||||
si->defs.defined |= _SI_LevelOneOnly;
|
||||
}
|
||||
else
|
||||
return ReportSIBadType(si, field, "level specification", info);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = ReportBadField("symbol interpretation", field, siText(si, info));
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
LookupEntry groupNames[] = {
|
||||
{"group1", 0x01}
|
||||
,
|
||||
{"group2", 0x02}
|
||||
,
|
||||
{"group3", 0x04}
|
||||
,
|
||||
{"group4", 0x08}
|
||||
,
|
||||
{"group5", 0x10}
|
||||
,
|
||||
{"group6", 0x20}
|
||||
,
|
||||
{"group7", 0x40}
|
||||
,
|
||||
{"group8", 0x80}
|
||||
,
|
||||
{"none", 0x00}
|
||||
,
|
||||
{"all", 0xff}
|
||||
,
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
HandleInterpVar(VarDef * stmt, XkbDescPtr xkb, CompatInfo * info)
|
||||
{
|
||||
ExprResult elem, field;
|
||||
ExprDef *ndx;
|
||||
|
||||
if (ExprResolveLhs(stmt->name, &elem, &field, &ndx) == 0)
|
||||
return 0; /* internal error, already reported */
|
||||
if (elem.str && (uStrCaseCmp(elem.str, "interpret") == 0))
|
||||
return SetInterpField(&info->dflt, xkb, field.str, ndx, stmt->value,
|
||||
info);
|
||||
if (elem.str && (uStrCaseCmp(elem.str, "indicator") == 0))
|
||||
{
|
||||
return SetIndicatorMapField(&info->ledDflt, xkb, field.str, ndx,
|
||||
stmt->value);
|
||||
}
|
||||
return SetActionField(xkb, elem.str, field.str, ndx, stmt->value,
|
||||
&info->act);
|
||||
}
|
||||
|
||||
static int
|
||||
HandleInterpBody(VarDef * def, XkbDescPtr xkb, SymInterpInfo * si,
|
||||
CompatInfo * info)
|
||||
{
|
||||
int ok = 1;
|
||||
ExprResult tmp, field;
|
||||
ExprDef *arrayNdx;
|
||||
|
||||
for (; def != NULL; def = (VarDef *) def->common.next)
|
||||
{
|
||||
if ((def->name) && (def->name->type == ExprFieldRef))
|
||||
{
|
||||
ok = HandleInterpVar(def, xkb, info);
|
||||
continue;
|
||||
}
|
||||
ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
|
||||
if (ok)
|
||||
ok = SetInterpField(si, xkb, field.str, arrayNdx, def->value,
|
||||
info);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
HandleInterpDef(InterpDef * def, XkbDescPtr xkb, unsigned merge,
|
||||
CompatInfo * info)
|
||||
{
|
||||
unsigned pred, mods;
|
||||
SymInterpInfo si;
|
||||
|
||||
if (!ResolveStateAndPredicate(def->match, &pred, &mods, info))
|
||||
{
|
||||
ERROR("Couldn't determine matching modifiers\n");
|
||||
ACTION("Symbol interpretation ignored\n");
|
||||
return False;
|
||||
}
|
||||
if (def->merge != MergeDefault)
|
||||
merge = def->merge;
|
||||
|
||||
si = info->dflt;
|
||||
si.defs.merge = merge;
|
||||
si.interp.sym = def->sym;
|
||||
si.interp.match = pred & XkbSI_OpMask;
|
||||
si.interp.mods = mods;
|
||||
if (!HandleInterpBody(def->def, xkb, &si, info))
|
||||
{
|
||||
info->errorCount++;
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!AddInterp(info, &si))
|
||||
{
|
||||
info->errorCount++;
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static int
|
||||
HandleGroupCompatDef(GroupCompatDef * def,
|
||||
XkbDescPtr xkb, unsigned merge, CompatInfo * info)
|
||||
{
|
||||
ExprResult val;
|
||||
GroupCompatInfo tmp;
|
||||
|
||||
if (def->merge != MergeDefault)
|
||||
merge = def->merge;
|
||||
if (!XkbIsLegalGroup(def->group - 1))
|
||||
{
|
||||
ERROR1("Keyboard group must be in the range 1..%d\n",
|
||||
XkbNumKbdGroups + 1);
|
||||
ACTION1("Compatibility map for illegal group %d ignored\n",
|
||||
def->group);
|
||||
return False;
|
||||
}
|
||||
tmp.fileID = info->fileID;
|
||||
tmp.merge = merge;
|
||||
if (!ExprResolveModMask(def->def, &val, LookupVModMask, (XPointer) xkb))
|
||||
{
|
||||
ERROR("Expected a modifier mask in group compatibility definition\n");
|
||||
ACTION1("Ignoring illegal compatibility map for group %d\n",
|
||||
def->group);
|
||||
return False;
|
||||
}
|
||||
tmp.real_mods = val.uval & 0xff;
|
||||
tmp.vmods = (val.uval >> 8) & 0xffff;
|
||||
return AddGroupCompat(info, def->group - 1, &tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleCompatMapFile(XkbFile * file,
|
||||
XkbDescPtr xkb, unsigned merge, CompatInfo * info)
|
||||
{
|
||||
ParseCommon *stmt;
|
||||
|
||||
if (merge == MergeDefault)
|
||||
merge = MergeAugment;
|
||||
info->name = uStringDup(file->name);
|
||||
stmt = file->defs;
|
||||
while (stmt)
|
||||
{
|
||||
switch (stmt->stmtType)
|
||||
{
|
||||
case StmtInclude:
|
||||
if (!HandleIncludeCompatMap((IncludeStmt *) stmt, xkb, info,
|
||||
HandleCompatMapFile))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtInterpDef:
|
||||
if (!HandleInterpDef((InterpDef *) stmt, xkb, merge, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtGroupCompatDef:
|
||||
if (!HandleGroupCompatDef
|
||||
((GroupCompatDef *) stmt, xkb, merge, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtIndicatorMapDef:
|
||||
{
|
||||
LEDInfo *rtrn;
|
||||
rtrn = HandleIndicatorMapDef((IndicatorMapDef *) stmt, xkb,
|
||||
&info->ledDflt, info->leds, merge);
|
||||
if (rtrn != NULL)
|
||||
info->leds = rtrn;
|
||||
else
|
||||
info->errorCount++;
|
||||
}
|
||||
break;
|
||||
case StmtVarDef:
|
||||
if (!HandleInterpVar((VarDef *) stmt, xkb, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtVModDef:
|
||||
if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtKeycodeDef:
|
||||
ERROR("Interpretation files may not include other types\n");
|
||||
ACTION("Ignoring definition of key name\n");
|
||||
info->errorCount++;
|
||||
break;
|
||||
default:
|
||||
WSGO1("Unexpected statement type %d in HandleCompatMapFile\n",
|
||||
stmt->stmtType);
|
||||
break;
|
||||
}
|
||||
stmt = stmt->next;
|
||||
if (info->errorCount > 10)
|
||||
{
|
||||
#ifdef NOISY
|
||||
ERROR("Too many errors\n");
|
||||
#endif
|
||||
ACTION1("Abandoning compatibility map \"%s\"\n", file->topName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
CopyInterps(CompatInfo * info,
|
||||
XkbCompatMapPtr compat, Bool needSymbol, unsigned pred)
|
||||
{
|
||||
SymInterpInfo *si;
|
||||
|
||||
for (si = info->interps; si; si = (SymInterpInfo *) si->defs.next)
|
||||
{
|
||||
if (((si->interp.match & XkbSI_OpMask) != pred) ||
|
||||
(needSymbol && (si->interp.sym == NoSymbol)) ||
|
||||
((!needSymbol) && (si->interp.sym != NoSymbol)))
|
||||
continue;
|
||||
if (compat->num_si >= compat->size_si)
|
||||
{
|
||||
WSGO("No room to merge symbol interpretations\n");
|
||||
ACTION("Symbol interpretations lost\n");
|
||||
return;
|
||||
}
|
||||
compat->sym_interpret[compat->num_si++] = si->interp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Bool
|
||||
CompileCompatMap(XkbFile * file,
|
||||
XkbFileInfo * result, unsigned merge, LEDInfo ** unboundLEDs)
|
||||
{
|
||||
int i;
|
||||
CompatInfo info;
|
||||
XkbDescPtr xkb;
|
||||
GroupCompatInfo *gcm;
|
||||
|
||||
xkb = result->xkb;
|
||||
InitCompatInfo(&info, xkb);
|
||||
info.dflt.defs.merge = merge;
|
||||
info.ledDflt.defs.merge = merge;
|
||||
HandleCompatMapFile(file, xkb, merge, &info);
|
||||
|
||||
if (info.errorCount == 0)
|
||||
{
|
||||
int size;
|
||||
if (XkbAllocCompatMap(xkb, XkbAllCompatMask, info.nInterps) !=
|
||||
Success)
|
||||
{
|
||||
WSGO("Couldn't allocate compatibility map\n");
|
||||
ACTION("Exiting\n");
|
||||
return False;
|
||||
}
|
||||
if (info.name != NULL)
|
||||
{
|
||||
if (XkbAllocNames(xkb, XkbCompatNameMask, 0, 0) == Success)
|
||||
xkb->names->compat =
|
||||
XkbInternAtom(xkb->dpy, info.name, False);
|
||||
else
|
||||
{
|
||||
WSGO("Couldn't allocate space for compat name\n");
|
||||
ACTION2("Name \"%s\" (from %s) NOT assigned\n",
|
||||
scanFile, info.name);
|
||||
}
|
||||
}
|
||||
size = info.nInterps * sizeof(XkbSymInterpretRec);
|
||||
if (size > 0)
|
||||
{
|
||||
CopyInterps(&info, xkb->compat, True, XkbSI_Exactly);
|
||||
CopyInterps(&info, xkb->compat, True, XkbSI_AllOf | XkbSI_NoneOf);
|
||||
CopyInterps(&info, xkb->compat, True, XkbSI_AnyOf);
|
||||
CopyInterps(&info, xkb->compat, True, XkbSI_AnyOfOrNone);
|
||||
CopyInterps(&info, xkb->compat, False, XkbSI_Exactly);
|
||||
CopyInterps(&info, xkb->compat, False,
|
||||
XkbSI_AllOf | XkbSI_NoneOf);
|
||||
CopyInterps(&info, xkb->compat, False, XkbSI_AnyOf);
|
||||
CopyInterps(&info, xkb->compat, False, XkbSI_AnyOfOrNone);
|
||||
}
|
||||
for (i = 0, gcm = &info.groupCompat[0]; i < XkbNumKbdGroups;
|
||||
i++, gcm++)
|
||||
{
|
||||
if ((gcm->fileID != 0) || (gcm->real_mods != 0)
|
||||
|| (gcm->vmods != 0))
|
||||
{
|
||||
xkb->compat->groups[i].mask = gcm->real_mods;
|
||||
xkb->compat->groups[i].real_mods = gcm->real_mods;
|
||||
xkb->compat->groups[i].vmods = gcm->vmods;
|
||||
}
|
||||
}
|
||||
if (info.leds != NULL)
|
||||
{
|
||||
if (!CopyIndicatorMapDefs(result, info.leds, unboundLEDs))
|
||||
info.errorCount++;
|
||||
info.leds = NULL;
|
||||
}
|
||||
ClearCompatInfo(&info, xkb);
|
||||
return True;
|
||||
}
|
||||
if (info.interps != NULL)
|
||||
uFree(info.interps);
|
||||
return False;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H 1
|
||||
|
||||
extern LookupEntry groupNames[];
|
||||
|
||||
#endif /* COMPAT_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,172 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef EXPR_H
|
||||
#define EXPR_H 1
|
||||
|
||||
typedef union _ExprResult
|
||||
{
|
||||
char *str;
|
||||
int ival;
|
||||
unsigned uval;
|
||||
XkbKeyNameRec keyName;
|
||||
} ExprResult;
|
||||
|
||||
typedef Bool(*IdentLookupFunc) (XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern char *exprTypeText(unsigned /* type */
|
||||
);
|
||||
|
||||
extern int ExprResolveLhs(ExprDef * /* expr */ ,
|
||||
ExprResult * /* elem_rtrn */ ,
|
||||
ExprResult * /* field_rtrn */ ,
|
||||
ExprDef ** /* index_rtrn */
|
||||
);
|
||||
|
||||
typedef struct _LookupPriv
|
||||
{
|
||||
XPointer priv;
|
||||
IdentLookupFunc chain;
|
||||
XPointer chainPriv;
|
||||
} LookupPriv;
|
||||
|
||||
typedef struct _LookupEntry
|
||||
{
|
||||
const char *name;
|
||||
unsigned result;
|
||||
} LookupEntry;
|
||||
|
||||
typedef struct _LookupTable
|
||||
{
|
||||
char *element;
|
||||
LookupEntry *entries;
|
||||
struct _LookupTable *nextElement;
|
||||
} LookupTable;
|
||||
|
||||
|
||||
extern char *exprOpText(unsigned /* type */
|
||||
);
|
||||
|
||||
extern int RadioLookup(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int SimpleLookup(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int TableLookup(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int LookupModIndex(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int LookupModMask(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int ExprResolveModIndex(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveModMask(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* priv */
|
||||
);
|
||||
|
||||
extern int ExprResolveBoolean(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveInteger(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveFloat(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveString(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveKeyName(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveEnum(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
LookupEntry * /* values */
|
||||
);
|
||||
|
||||
extern int ExprResolveMask(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
extern int ExprResolveKeySym(ExprDef * /* expr */ ,
|
||||
ExprResult * /* val_rtrn */ ,
|
||||
IdentLookupFunc /* lookup */ ,
|
||||
XPointer /* lookupPriv */
|
||||
);
|
||||
|
||||
#endif /* EXPR_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,575 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "misc.h"
|
||||
#include "tokens.h"
|
||||
#include "expr.h"
|
||||
#include "vmod.h"
|
||||
#include "indicators.h"
|
||||
#include "action.h"
|
||||
#include "compat.h"
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#define ReportIndicatorBadType(d,l,f,w) \
|
||||
ReportBadType("indicator map",(f),\
|
||||
XkbAtomText((d),(l)->name,XkbMessage),(w))
|
||||
#define ReportIndicatorNotArray(d,l,f) \
|
||||
ReportNotArray("indicator map",(f),\
|
||||
XkbAtomText((d),(l)->name,XkbMessage))
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
ClearIndicatorMapInfo(Display * dpy, LEDInfo * info)
|
||||
{
|
||||
info->name = XkbInternAtom(dpy, "default", False);
|
||||
info->indicator = _LED_NotBound;
|
||||
info->flags = info->which_mods = info->real_mods = 0;
|
||||
info->vmods = 0;
|
||||
info->which_groups = info->groups = 0;
|
||||
info->ctrls = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
LEDInfo *
|
||||
AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new)
|
||||
{
|
||||
LEDInfo *old, *last;
|
||||
unsigned collide;
|
||||
|
||||
last = NULL;
|
||||
for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next)
|
||||
{
|
||||
if (old->name == new->name)
|
||||
{
|
||||
if ((old->real_mods == new->real_mods) &&
|
||||
(old->vmods == new->vmods) &&
|
||||
(old->groups == new->groups) &&
|
||||
(old->ctrls == new->ctrls) &&
|
||||
(old->which_mods == new->which_mods) &&
|
||||
(old->which_groups == new->which_groups))
|
||||
{
|
||||
old->defs.defined |= new->defs.defined;
|
||||
return oldLEDs;
|
||||
}
|
||||
if (new->defs.merge == MergeReplace)
|
||||
{
|
||||
CommonInfo *next = old->defs.next;
|
||||
if (((old->defs.fileID == new->defs.fileID)
|
||||
&& (warningLevel > 0)) || (warningLevel > 9))
|
||||
{
|
||||
WARN1("Map for indicator %s redefined\n",
|
||||
XkbAtomText(NULL, old->name, XkbMessage));
|
||||
ACTION("Earlier definition ignored\n");
|
||||
}
|
||||
*old = *new;
|
||||
old->defs.next = next;
|
||||
return oldLEDs;
|
||||
}
|
||||
collide = 0;
|
||||
if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->indicator = new->indicator;
|
||||
old->defs.defined |= _LED_Index;
|
||||
}
|
||||
if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->which_mods = new->which_mods;
|
||||
old->real_mods = new->real_mods;
|
||||
old->vmods = new->vmods;
|
||||
old->defs.defined |= _LED_Mods;
|
||||
}
|
||||
if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->which_groups = new->which_groups;
|
||||
old->groups = new->groups;
|
||||
old->defs.defined |= _LED_Groups;
|
||||
}
|
||||
if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->ctrls = new->ctrls;
|
||||
old->defs.defined |= _LED_Ctrls;
|
||||
}
|
||||
if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->flags &= ~XkbIM_NoExplicit;
|
||||
old->flags |= (new->flags & XkbIM_NoExplicit);
|
||||
old->defs.defined |= _LED_Explicit;
|
||||
}
|
||||
if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->flags &= ~XkbIM_NoAutomatic;
|
||||
old->flags |= (new->flags & XkbIM_NoAutomatic);
|
||||
old->defs.defined |= _LED_Automatic;
|
||||
}
|
||||
if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide))
|
||||
{
|
||||
old->flags &= ~XkbIM_LEDDrivesKB;
|
||||
old->flags |= (new->flags & XkbIM_LEDDrivesKB);
|
||||
old->defs.defined |= _LED_DrivesKbd;
|
||||
}
|
||||
if (collide)
|
||||
{
|
||||
WARN1("Map for indicator %s redefined\n",
|
||||
XkbAtomText(NULL, old->name, XkbMessage));
|
||||
ACTION1("Using %s definition for duplicate fields\n",
|
||||
(new->defs.merge == MergeAugment ? "first" : "last"));
|
||||
}
|
||||
return oldLEDs;
|
||||
}
|
||||
if (old->defs.next == NULL)
|
||||
last = old;
|
||||
}
|
||||
/* new definition */
|
||||
old = uTypedAlloc(LEDInfo);
|
||||
if (!old)
|
||||
{
|
||||
WSGO("Couldn't allocate indicator map\n");
|
||||
ACTION1("Map for indicator %s not compiled\n",
|
||||
XkbAtomText(NULL, new->name, XkbMessage));
|
||||
return NULL;
|
||||
}
|
||||
*old = *new;
|
||||
old->defs.next = NULL;
|
||||
if (last)
|
||||
{
|
||||
last->defs.next = &old->defs;
|
||||
return oldLEDs;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
static LookupEntry modComponentNames[] = {
|
||||
{"base", XkbIM_UseBase}
|
||||
,
|
||||
{"latched", XkbIM_UseLatched}
|
||||
,
|
||||
{"locked", XkbIM_UseLocked}
|
||||
,
|
||||
{"effective", XkbIM_UseEffective}
|
||||
,
|
||||
{"compat", XkbIM_UseCompat}
|
||||
,
|
||||
{"any", XkbIM_UseAnyMods}
|
||||
,
|
||||
{"none", 0}
|
||||
,
|
||||
{NULL, 0}
|
||||
};
|
||||
static LookupEntry groupComponentNames[] = {
|
||||
{"base", XkbIM_UseBase}
|
||||
,
|
||||
{"latched", XkbIM_UseLatched}
|
||||
,
|
||||
{"locked", XkbIM_UseLocked}
|
||||
,
|
||||
{"effective", XkbIM_UseEffective}
|
||||
,
|
||||
{"any", XkbIM_UseAnyGroup}
|
||||
,
|
||||
{"none", 0}
|
||||
,
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
int
|
||||
SetIndicatorMapField(LEDInfo * led,
|
||||
XkbDescPtr xkb,
|
||||
char *field, ExprDef * arrayNdx, ExprDef * value)
|
||||
{
|
||||
ExprResult rtrn;
|
||||
Bool ok;
|
||||
|
||||
ok = True;
|
||||
if ((uStrCaseCmp(field, "modifiers") == 0)
|
||||
|| (uStrCaseCmp(field, "mods") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field,
|
||||
"modifier mask");
|
||||
led->real_mods = rtrn.uval & 0xff;
|
||||
led->vmods = (rtrn.uval >> 8) & 0xff;
|
||||
led->defs.defined |= _LED_Mods;
|
||||
}
|
||||
else if (uStrCaseCmp(field, "groups") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveMask
|
||||
(value, &rtrn, SimpleLookup, (XPointer) groupNames))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field, "group mask");
|
||||
led->groups = rtrn.uval;
|
||||
led->defs.defined |= _LED_Groups;
|
||||
}
|
||||
else if ((uStrCaseCmp(field, "controls") == 0) ||
|
||||
(uStrCaseCmp(field, "ctrls") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveMask
|
||||
(value, &rtrn, SimpleLookup, (XPointer) ctrlNames))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field,
|
||||
"controls mask");
|
||||
led->ctrls = rtrn.uval;
|
||||
led->defs.defined |= _LED_Ctrls;
|
||||
}
|
||||
else if (uStrCaseCmp(field, "allowexplicit") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
|
||||
if (rtrn.uval)
|
||||
led->flags &= ~XkbIM_NoExplicit;
|
||||
else
|
||||
led->flags |= XkbIM_NoExplicit;
|
||||
led->defs.defined |= _LED_Explicit;
|
||||
}
|
||||
else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
|
||||
(uStrCaseCmp(field, "whichmodifierstate") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveMask(value, &rtrn, SimpleLookup,
|
||||
(XPointer) modComponentNames))
|
||||
{
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field,
|
||||
"mask of modifier state components");
|
||||
}
|
||||
led->which_mods = rtrn.uval;
|
||||
}
|
||||
else if (uStrCaseCmp(field, "whichgroupstate") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveMask(value, &rtrn, SimpleLookup,
|
||||
(XPointer) groupComponentNames))
|
||||
{
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field,
|
||||
"mask of group state components");
|
||||
}
|
||||
led->which_groups = rtrn.uval;
|
||||
}
|
||||
else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
|
||||
(uStrCaseCmp(field, "driveskeyboard") == 0) ||
|
||||
(uStrCaseCmp(field, "leddriveskbd") == 0) ||
|
||||
(uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
|
||||
(uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
|
||||
(uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
|
||||
if (rtrn.uval)
|
||||
led->flags |= XkbIM_LEDDrivesKB;
|
||||
else
|
||||
led->flags &= ~XkbIM_LEDDrivesKB;
|
||||
led->defs.defined |= _LED_DrivesKbd;
|
||||
}
|
||||
else if (uStrCaseCmp(field, "index") == 0)
|
||||
{
|
||||
if (arrayNdx != NULL)
|
||||
return ReportIndicatorNotArray(xkb->dpy, led, field);
|
||||
if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
|
||||
return ReportIndicatorBadType(xkb->dpy, led, field,
|
||||
"indicator index");
|
||||
if ((rtrn.uval < 1) || (rtrn.uval > 32))
|
||||
{
|
||||
ERROR2("Illegal indicator index %d (range 1..%d)\n",
|
||||
rtrn.uval, XkbNumIndicators);
|
||||
ACTION1("Index definition for %s indicator ignored\n",
|
||||
XkbAtomText(NULL, led->name, XkbMessage));
|
||||
return False;
|
||||
}
|
||||
led->indicator = rtrn.uval;
|
||||
led->defs.defined |= _LED_Index;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR2("Unknown field %s in map for %s indicator\n", field,
|
||||
XkbAtomText(NULL, led->name, XkbMessage));
|
||||
ACTION("Definition ignored\n");
|
||||
ok = False;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
LEDInfo *
|
||||
HandleIndicatorMapDef(IndicatorMapDef * def,
|
||||
XkbDescPtr xkb,
|
||||
LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
|
||||
{
|
||||
LEDInfo led, *rtrn;
|
||||
VarDef *var;
|
||||
Bool ok;
|
||||
|
||||
if (def->merge != MergeDefault)
|
||||
merge = def->merge;
|
||||
|
||||
led = *dflt;
|
||||
led.defs.merge = merge;
|
||||
led.name = def->name;
|
||||
|
||||
ok = True;
|
||||
for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
|
||||
{
|
||||
ExprResult elem, field;
|
||||
ExprDef *arrayNdx;
|
||||
if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
|
||||
{
|
||||
ok = False;
|
||||
continue;
|
||||
}
|
||||
if (elem.str != NULL)
|
||||
{
|
||||
ERROR1
|
||||
("Cannot set defaults for \"%s\" element in indicator map\n",
|
||||
elem.str);
|
||||
ACTION2("Assignment to %s.%s ignored\n", elem.str, field.str);
|
||||
ok = False;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
|
||||
var->value) && ok;
|
||||
}
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
rtrn = AddIndicatorMap(oldLEDs, &led);
|
||||
return rtrn;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
CopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds,
|
||||
LEDInfo ** unboundRtrn)
|
||||
{
|
||||
LEDInfo *led, *next;
|
||||
LEDInfo *unbound, *last;
|
||||
XkbDescPtr xkb;
|
||||
|
||||
xkb = result->xkb;
|
||||
if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
|
||||
{
|
||||
WSGO("Couldn't allocate names\n");
|
||||
ACTION("Indicator names may be incorrect\n");
|
||||
}
|
||||
if (XkbAllocIndicatorMaps(xkb) != Success)
|
||||
{
|
||||
WSGO("Can't allocate indicator maps\n");
|
||||
ACTION("Indicator map definitions may be lost\n");
|
||||
return False;
|
||||
}
|
||||
last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
|
||||
while ((last != NULL) && (last->defs.next != NULL))
|
||||
{
|
||||
last = (LEDInfo *) last->defs.next;
|
||||
}
|
||||
for (led = leds; led != NULL; led = next)
|
||||
{
|
||||
next = (LEDInfo *) led->defs.next;
|
||||
if ((led->groups != 0) && (led->which_groups == 0))
|
||||
led->which_groups = XkbIM_UseEffective;
|
||||
if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
|
||||
led->which_mods = XkbIM_UseEffective;
|
||||
if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
|
||||
{
|
||||
if (unboundRtrn != NULL)
|
||||
{
|
||||
led->defs.next = NULL;
|
||||
if (last != NULL)
|
||||
last->defs.next = (CommonInfo *) led;
|
||||
else
|
||||
unbound = led;
|
||||
last = led;
|
||||
}
|
||||
else
|
||||
uFree(led);
|
||||
}
|
||||
else
|
||||
{
|
||||
register XkbIndicatorMapPtr im;
|
||||
im = &xkb->indicators->maps[led->indicator - 1];
|
||||
im->flags = led->flags;
|
||||
im->which_groups = led->which_groups;
|
||||
im->groups = led->groups;
|
||||
im->which_mods = led->which_mods;
|
||||
im->mods.mask = led->real_mods;
|
||||
im->mods.real_mods = led->real_mods;
|
||||
im->mods.vmods = led->vmods;
|
||||
im->ctrls = led->ctrls;
|
||||
if (xkb->names != NULL)
|
||||
xkb->names->indicators[led->indicator - 1] = led->name;
|
||||
uFree(led);
|
||||
}
|
||||
}
|
||||
if (unboundRtrn != NULL)
|
||||
{
|
||||
*unboundRtrn = unbound;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
BindIndicators(XkbFileInfo * result,
|
||||
Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn)
|
||||
{
|
||||
XkbDescPtr xkb;
|
||||
register int i;
|
||||
register LEDInfo *led, *next, *last;
|
||||
|
||||
xkb = result->xkb;
|
||||
if (xkb->names != NULL)
|
||||
{
|
||||
for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
|
||||
{
|
||||
if (led->indicator == _LED_NotBound)
|
||||
{
|
||||
for (i = 0; i < XkbNumIndicators; i++)
|
||||
{
|
||||
if (xkb->names->indicators[i] == led->name)
|
||||
{
|
||||
led->indicator = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (force)
|
||||
{
|
||||
for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
|
||||
{
|
||||
if (led->indicator == _LED_NotBound)
|
||||
{
|
||||
for (i = 0; i < XkbNumIndicators; i++)
|
||||
{
|
||||
if (xkb->names->indicators[i] == None)
|
||||
{
|
||||
xkb->names->indicators[i] = led->name;
|
||||
led->indicator = i + 1;
|
||||
xkb->indicators->phys_indicators &= ~(1 << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (led->indicator == _LED_NotBound)
|
||||
{
|
||||
ERROR("No unnamed indicators found\n");
|
||||
ACTION1
|
||||
("Virtual indicator map \"%s\" not bound\n",
|
||||
XkbAtomGetString(xkb->dpy, led->name));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (last = NULL, led = unbound; led != NULL; led = next)
|
||||
{
|
||||
next = (LEDInfo *) led->defs.next;
|
||||
if (led->indicator == _LED_NotBound)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
unbound = next;
|
||||
uFree(led);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (last)
|
||||
last->defs.next = &led->defs;
|
||||
else
|
||||
unbound = led;
|
||||
last = led;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((xkb->names != NULL) &&
|
||||
(xkb->names->indicators[led->indicator - 1] != led->name))
|
||||
{
|
||||
Atom old = xkb->names->indicators[led->indicator - 1];
|
||||
ERROR1("Multiple names bound to indicator %d\n",
|
||||
(unsigned int) led->indicator);
|
||||
ACTION2("Using %s, ignoring %s\n",
|
||||
XkbAtomGetString(xkb->dpy, old),
|
||||
XkbAtomGetString(xkb->dpy, led->name));
|
||||
led->indicator = _LED_NotBound;
|
||||
if (force)
|
||||
{
|
||||
uFree(led);
|
||||
unbound = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (last)
|
||||
last->defs.next = &led->defs;
|
||||
else
|
||||
unbound = led;
|
||||
last = led;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XkbIndicatorMapPtr map;
|
||||
map = &xkb->indicators->maps[led->indicator - 1];
|
||||
map->flags = led->flags;
|
||||
map->which_groups = led->which_groups;
|
||||
map->groups = led->groups;
|
||||
map->which_mods = led->which_mods;
|
||||
map->mods.mask = led->real_mods;
|
||||
map->mods.real_mods = led->real_mods;
|
||||
map->mods.vmods = led->vmods;
|
||||
map->ctrls = led->ctrls;
|
||||
if (last)
|
||||
last->defs.next = &next->defs;
|
||||
else
|
||||
unbound = next;
|
||||
led->defs.next = NULL;
|
||||
uFree(led);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unboundRtrn)
|
||||
{
|
||||
*unboundRtrn = unbound;
|
||||
}
|
||||
else if (unbound)
|
||||
{
|
||||
for (led = unbound; led != NULL; led = next)
|
||||
{
|
||||
next = (LEDInfo *) led->defs.next;
|
||||
uFree(led);
|
||||
}
|
||||
}
|
||||
return True;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef INDICATORS_H
|
||||
#define INDICATORS_H 1
|
||||
|
||||
#define _LED_Index (1<<0)
|
||||
#define _LED_Mods (1<<1)
|
||||
#define _LED_Groups (1<<2)
|
||||
#define _LED_Ctrls (1<<3)
|
||||
#define _LED_Explicit (1<<4)
|
||||
#define _LED_Automatic (1<<5)
|
||||
#define _LED_DrivesKbd (1<<6)
|
||||
|
||||
#define _LED_NotBound 255
|
||||
|
||||
typedef struct _LEDInfo
|
||||
{
|
||||
CommonInfo defs;
|
||||
Atom name;
|
||||
unsigned char indicator;
|
||||
unsigned char flags;
|
||||
unsigned char which_mods;
|
||||
unsigned char real_mods;
|
||||
unsigned short vmods;
|
||||
unsigned char which_groups;
|
||||
unsigned char groups;
|
||||
unsigned int ctrls;
|
||||
} LEDInfo;
|
||||
|
||||
extern void ClearIndicatorMapInfo(Display * /* dpy */ ,
|
||||
LEDInfo * /* info */
|
||||
);
|
||||
|
||||
|
||||
extern LEDInfo *AddIndicatorMap(LEDInfo * /* oldLEDs */ ,
|
||||
LEDInfo * /* newLED */
|
||||
);
|
||||
|
||||
extern int SetIndicatorMapField(LEDInfo * /* led */ ,
|
||||
XkbDescPtr /* xkb */ ,
|
||||
char * /* field */ ,
|
||||
ExprDef * /* arrayNdx */ ,
|
||||
ExprDef * /* value */
|
||||
);
|
||||
|
||||
extern LEDInfo *HandleIndicatorMapDef(IndicatorMapDef * /* stmt */ ,
|
||||
XkbDescPtr /* xkb */ ,
|
||||
LEDInfo * /* dflt */ ,
|
||||
LEDInfo * /* oldLEDs */ ,
|
||||
unsigned /* mergeMode */
|
||||
);
|
||||
|
||||
extern Bool CopyIndicatorMapDefs(XkbFileInfo * /* result */ ,
|
||||
LEDInfo * /* leds */ ,
|
||||
LEDInfo ** /* unboundRtrn */
|
||||
);
|
||||
|
||||
extern Bool BindIndicators(XkbFileInfo * /* result */ ,
|
||||
Bool /* force */ ,
|
||||
LEDInfo * /* unbound */ ,
|
||||
LEDInfo ** /* unboundRtrn */
|
||||
);
|
||||
|
||||
#endif /* INDICATORS_H */
|
|
@ -0,0 +1,896 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "tokens.h"
|
||||
#include "expr.h"
|
||||
#include "keycodes.h"
|
||||
#include "misc.h"
|
||||
#include "alias.h"
|
||||
|
||||
char *
|
||||
longText(unsigned long val, unsigned format)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
LongToKeyName(val, buf);
|
||||
return XkbKeyNameText(buf, format);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
LongToKeyName(unsigned long val, char *name)
|
||||
{
|
||||
name[0] = ((val >> 24) & 0xff);
|
||||
name[1] = ((val >> 16) & 0xff);
|
||||
name[2] = ((val >> 8) & 0xff);
|
||||
name[3] = (val & 0xff);
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
typedef struct _IndicatorNameInfo
|
||||
{
|
||||
CommonInfo defs;
|
||||
int ndx;
|
||||
Atom name;
|
||||
Bool virtual;
|
||||
} IndicatorNameInfo;
|
||||
|
||||
typedef struct _KeyNamesInfo
|
||||
{
|
||||
char *name; /* e.g. evdev+aliases(qwerty) */
|
||||
int errorCount;
|
||||
unsigned fileID;
|
||||
unsigned merge;
|
||||
int computedMin; /* lowest keycode stored */
|
||||
int computedMax; /* highest keycode stored */
|
||||
int explicitMin;
|
||||
int explicitMax;
|
||||
int effectiveMin;
|
||||
int effectiveMax;
|
||||
unsigned long names[XkbMaxLegalKeyCode + 1]; /* 4-letter name of key, keycode is the index */
|
||||
unsigned files[XkbMaxLegalKeyCode + 1];
|
||||
unsigned char has_alt_forms[XkbMaxLegalKeyCode + 1];
|
||||
IndicatorNameInfo *leds;
|
||||
AliasInfo *aliases;
|
||||
} KeyNamesInfo;
|
||||
|
||||
static void HandleKeycodesFile(XkbFile * file,
|
||||
XkbDescPtr xkb,
|
||||
unsigned merge,
|
||||
KeyNamesInfo * info);
|
||||
|
||||
static void
|
||||
InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
|
||||
{
|
||||
ii->defs.defined = 0;
|
||||
ii->defs.merge = info->merge;
|
||||
ii->defs.fileID = info->fileID;
|
||||
ii->defs.next = NULL;
|
||||
ii->ndx = 0;
|
||||
ii->name = None;
|
||||
ii->virtual = False;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
|
||||
{
|
||||
if (ii == info->leds)
|
||||
{
|
||||
ClearCommonInfo(&ii->defs);
|
||||
info->leds = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static IndicatorNameInfo *
|
||||
NextIndicatorName(KeyNamesInfo * info)
|
||||
{
|
||||
IndicatorNameInfo *ii;
|
||||
|
||||
ii = uTypedAlloc(IndicatorNameInfo);
|
||||
if (ii)
|
||||
{
|
||||
InitIndicatorNameInfo(ii, info);
|
||||
info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
|
||||
(CommonInfo *) ii);
|
||||
}
|
||||
return ii;
|
||||
}
|
||||
|
||||
static IndicatorNameInfo *
|
||||
FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
|
||||
{
|
||||
IndicatorNameInfo *old;
|
||||
|
||||
for (old = info->leds; old != NULL;
|
||||
old = (IndicatorNameInfo *) old->defs.next)
|
||||
{
|
||||
if (old->ndx == ndx)
|
||||
return old;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static IndicatorNameInfo *
|
||||
FindIndicatorByName(KeyNamesInfo * info, Atom name)
|
||||
{
|
||||
IndicatorNameInfo *old;
|
||||
|
||||
for (old = info->leds; old != NULL;
|
||||
old = (IndicatorNameInfo *) old->defs.next)
|
||||
{
|
||||
if (old->name == name)
|
||||
return old;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Bool
|
||||
AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
|
||||
{
|
||||
IndicatorNameInfo *old;
|
||||
Bool replace;
|
||||
const char *action;
|
||||
|
||||
replace = (new->defs.merge == MergeReplace) ||
|
||||
(new->defs.merge == MergeOverride);
|
||||
old = FindIndicatorByName(info, new->name);
|
||||
if (old)
|
||||
{
|
||||
if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
|
||||
|| (warningLevel > 9))
|
||||
{
|
||||
WARN1("Multiple indicators named %s\n",
|
||||
XkbAtomText(NULL, new->name, XkbMessage));
|
||||
if (old->ndx == new->ndx)
|
||||
{
|
||||
if (old->virtual != new->virtual)
|
||||
{
|
||||
if (replace)
|
||||
old->virtual = new->virtual;
|
||||
action = "Using %s instead of %s\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
action = "Identical definitions ignored\n";
|
||||
}
|
||||
ACTION2(action, (old->virtual ? "virtual" : "real"),
|
||||
(old->virtual ? "real" : "virtual"));
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (replace)
|
||||
action = "Ignoring %d, using %d\n";
|
||||
else
|
||||
action = "Using %d, ignoring %d\n";
|
||||
ACTION2(action, old->ndx, new->ndx);
|
||||
}
|
||||
if (replace)
|
||||
{
|
||||
if (info->leds == old)
|
||||
info->leds = (IndicatorNameInfo *) old->defs.next;
|
||||
else
|
||||
{
|
||||
IndicatorNameInfo *tmp;
|
||||
tmp = info->leds;
|
||||
for (; tmp != NULL;
|
||||
tmp = (IndicatorNameInfo *) tmp->defs.next)
|
||||
{
|
||||
if (tmp->defs.next == (CommonInfo *) old)
|
||||
{
|
||||
tmp->defs.next = old->defs.next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
uFree(old);
|
||||
}
|
||||
}
|
||||
}
|
||||
old = FindIndicatorByIndex(info, new->ndx);
|
||||
if (old)
|
||||
{
|
||||
if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
|
||||
|| (warningLevel > 9))
|
||||
{
|
||||
WARN1("Multiple names for indicator %d\n", new->ndx);
|
||||
if ((old->name == new->name) && (old->virtual == new->virtual))
|
||||
action = "Identical definitions ignored\n";
|
||||
else
|
||||
{
|
||||
const char *oldType, *newType;
|
||||
Atom using, ignoring;
|
||||
if (old->virtual)
|
||||
oldType = "virtual indicator";
|
||||
else
|
||||
oldType = "real indicator";
|
||||
if (new->virtual)
|
||||
newType = "virtual indicator";
|
||||
else
|
||||
newType = "real indicator";
|
||||
if (replace)
|
||||
{
|
||||
using = new->name;
|
||||
ignoring = old->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
using = old->name;
|
||||
ignoring = new->name;
|
||||
}
|
||||
ACTION4("Using %s %s, ignoring %s %s\n",
|
||||
oldType, XkbAtomText(NULL, using, XkbMessage),
|
||||
newType, XkbAtomText(NULL, ignoring, XkbMessage));
|
||||
}
|
||||
}
|
||||
if (replace)
|
||||
{
|
||||
old->name = new->name;
|
||||
old->virtual = new->virtual;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
old = new;
|
||||
new = NextIndicatorName(info);
|
||||
if (!new)
|
||||
{
|
||||
WSGO1("Couldn't allocate name for indicator %d\n", new->ndx);
|
||||
ACTION("Ignored\n");
|
||||
return False;
|
||||
}
|
||||
new->name = old->name;
|
||||
new->ndx = old->ndx;
|
||||
new->virtual = old->virtual;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearKeyNamesInfo(KeyNamesInfo * info)
|
||||
{
|
||||
if (info->name != NULL)
|
||||
uFree(info->name);
|
||||
info->name = NULL;
|
||||
info->computedMax = info->explicitMax = info->explicitMin = -1;
|
||||
info->computedMin = 256;
|
||||
info->effectiveMin = 8;
|
||||
info->effectiveMax = 255;
|
||||
bzero((char *) info->names, sizeof(info->names));
|
||||
bzero((char *) info->files, sizeof(info->files));
|
||||
bzero((char *) info->has_alt_forms, sizeof(info->has_alt_forms));
|
||||
if (info->leds)
|
||||
ClearIndicatorNameInfo(info->leds, info);
|
||||
if (info->aliases)
|
||||
ClearAliases(&info->aliases);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
InitKeyNamesInfo(KeyNamesInfo * info)
|
||||
{
|
||||
info->name = NULL;
|
||||
info->leds = NULL;
|
||||
info->aliases = NULL;
|
||||
ClearKeyNamesInfo(info);
|
||||
info->errorCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
FindKeyByLong(KeyNamesInfo * info, unsigned long name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = info->effectiveMin; i <= info->effectiveMax; i++)
|
||||
{
|
||||
if (info->names[i] == name)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the name of the key as a long in the info struct under the given
|
||||
* keycode. If the same keys is referred to twice, print a warning.
|
||||
* Note that the key's name is stored as a long, the keycode is the index.
|
||||
*/
|
||||
static Bool
|
||||
AddKeyName(KeyNamesInfo * info,
|
||||
int kc,
|
||||
char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
|
||||
{
|
||||
int old;
|
||||
unsigned long lval;
|
||||
|
||||
if ((kc < info->effectiveMin) || (kc > info->effectiveMax))
|
||||
{
|
||||
ERROR2("Illegal keycode %d for name <%s>\n", kc, name);
|
||||
ACTION2("Must be in the range %d-%d inclusive\n",
|
||||
info->effectiveMin, info->effectiveMax);
|
||||
return False;
|
||||
}
|
||||
if (kc < info->computedMin)
|
||||
info->computedMin = kc;
|
||||
if (kc > info->computedMax)
|
||||
info->computedMax = kc;
|
||||
lval = KeyNameToLong(name);
|
||||
|
||||
if (reportCollisions)
|
||||
{
|
||||
reportCollisions = ((warningLevel > 7) ||
|
||||
((warningLevel > 0)
|
||||
&& (fileID == info->files[kc])));
|
||||
}
|
||||
|
||||
if (info->names[kc] != 0)
|
||||
{
|
||||
char buf[6];
|
||||
|
||||
LongToKeyName(info->names[kc], buf);
|
||||
buf[4] = '\0';
|
||||
if (info->names[kc] == lval)
|
||||
{
|
||||
if (info->has_alt_forms[kc] || (merge == MergeAltForm))
|
||||
{
|
||||
info->has_alt_forms[kc] = True;
|
||||
}
|
||||
else if (reportCollisions)
|
||||
{
|
||||
WARN("Multiple identical key name definitions\n");
|
||||
ACTION2("Later occurences of \"<%s> = %d\" ignored\n",
|
||||
buf, kc);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
if (merge == MergeAugment)
|
||||
{
|
||||
if (reportCollisions)
|
||||
{
|
||||
WARN1("Multiple names for keycode %d\n", kc);
|
||||
ACTION2("Using <%s>, ignoring <%s>\n", buf, name);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reportCollisions)
|
||||
{
|
||||
WARN1("Multiple names for keycode %d\n", kc);
|
||||
ACTION2("Using <%s>, ignoring <%s>\n", name, buf);
|
||||
}
|
||||
info->names[kc] = 0;
|
||||
info->files[kc] = 0;
|
||||
}
|
||||
}
|
||||
old = FindKeyByLong(info, lval);
|
||||
if ((old != 0) && (old != kc))
|
||||
{
|
||||
if (merge == MergeOverride)
|
||||
{
|
||||
info->names[old] = 0;
|
||||
info->files[old] = 0;
|
||||
info->has_alt_forms[old] = True;
|
||||
if (reportCollisions)
|
||||
{
|
||||
WARN1("Key name <%s> assigned to multiple keys\n", name);
|
||||
ACTION2("Using %d, ignoring %d\n", kc, old);
|
||||
}
|
||||
}
|
||||
else if (merge != MergeAltForm)
|
||||
{
|
||||
if ((reportCollisions) && (warningLevel > 3))
|
||||
{
|
||||
WARN1("Key name <%s> assigned to multiple keys\n", name);
|
||||
ACTION2("Using %d, ignoring %d\n", old, kc);
|
||||
ACTION
|
||||
("Use 'alternate' keyword to assign the same name to multiple keys\n");
|
||||
}
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->has_alt_forms[old] = True;
|
||||
}
|
||||
}
|
||||
info->names[kc] = lval;
|
||||
info->files[kc] = fileID;
|
||||
info->has_alt_forms[kc] = (merge == MergeAltForm);
|
||||
return True;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
|
||||
unsigned merge)
|
||||
{
|
||||
register int i;
|
||||
char buf[5];
|
||||
|
||||
if (from->errorCount > 0)
|
||||
{
|
||||
into->errorCount += from->errorCount;
|
||||
return;
|
||||
}
|
||||
if (into->name == NULL)
|
||||
{
|
||||
into->name = from->name;
|
||||
from->name = NULL;
|
||||
}
|
||||
for (i = from->computedMin; i <= from->computedMax; i++)
|
||||
{
|
||||
unsigned thisMerge;
|
||||
if (from->names[i] == 0)
|
||||
continue;
|
||||
LongToKeyName(from->names[i], buf);
|
||||
buf[4] = '\0';
|
||||
if (from->has_alt_forms[i])
|
||||
thisMerge = MergeAltForm;
|
||||
else
|
||||
thisMerge = merge;
|
||||
if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
|
||||
into->errorCount++;
|
||||
}
|
||||
if (from->leds)
|
||||
{
|
||||
IndicatorNameInfo *led, *next;
|
||||
for (led = from->leds; led != NULL; led = next)
|
||||
{
|
||||
if (merge != MergeDefault)
|
||||
led->defs.merge = merge;
|
||||
if (!AddIndicatorName(into, led))
|
||||
into->errorCount++;
|
||||
next = (IndicatorNameInfo *) led->defs.next;
|
||||
}
|
||||
}
|
||||
if (!MergeAliases(&into->aliases, &from->aliases, merge))
|
||||
into->errorCount++;
|
||||
if (from->explicitMin > 0)
|
||||
{
|
||||
if ((into->explicitMin < 0)
|
||||
|| (into->explicitMin > from->explicitMin))
|
||||
into->effectiveMin = into->explicitMin = from->explicitMin;
|
||||
}
|
||||
if (from->explicitMax > 0)
|
||||
{
|
||||
if ((into->explicitMax < 0)
|
||||
|| (into->explicitMax < from->explicitMax))
|
||||
into->effectiveMax = into->explicitMax = from->explicitMax;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
|
||||
*
|
||||
* @param stmt The include statement from the keymap file.
|
||||
* @param xkb Unused for all but the xkb->flags.
|
||||
* @param info Struct to store the key info in.
|
||||
*/
|
||||
static Bool
|
||||
HandleIncludeKeycodes(IncludeStmt * stmt, XkbDescPtr xkb, KeyNamesInfo * info)
|
||||
{
|
||||
unsigned newMerge;
|
||||
XkbFile *rtrn;
|
||||
KeyNamesInfo included = {NULL};
|
||||
Bool haveSelf;
|
||||
|
||||
haveSelf = False;
|
||||
if ((stmt->file == NULL) && (stmt->map == NULL))
|
||||
{
|
||||
haveSelf = True;
|
||||
included = *info;
|
||||
bzero(info, sizeof(KeyNamesInfo));
|
||||
}
|
||||
else if (strcmp(stmt->file, "computed") == 0)
|
||||
{
|
||||
xkb->flags |= AutoKeyNames;
|
||||
info->explicitMin = XkbMinLegalKeyCode;
|
||||
info->explicitMax = XkbMaxLegalKeyCode;
|
||||
return (info->errorCount == 0);
|
||||
} /* parse file, store returned info in the xkb struct */
|
||||
else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
|
||||
{
|
||||
InitKeyNamesInfo(&included);
|
||||
HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
|
||||
if (stmt->stmt != NULL)
|
||||
{
|
||||
if (included.name != NULL)
|
||||
uFree(included.name);
|
||||
included.name = stmt->stmt;
|
||||
stmt->stmt = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->errorCount += 10; /* XXX: why 10?? */
|
||||
return False;
|
||||
}
|
||||
/* Do we have more than one include statement? */
|
||||
if ((stmt->next != NULL) && (included.errorCount < 1))
|
||||
{
|
||||
IncludeStmt *next;
|
||||
unsigned op;
|
||||
KeyNamesInfo next_incl;
|
||||
|
||||
for (next = stmt->next; next != NULL; next = next->next)
|
||||
{
|
||||
if ((next->file == NULL) && (next->map == NULL))
|
||||
{
|
||||
haveSelf = True;
|
||||
MergeIncludedKeycodes(&included, info, next->merge);
|
||||
ClearKeyNamesInfo(info);
|
||||
}
|
||||
else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
|
||||
{
|
||||
InitKeyNamesInfo(&next_incl);
|
||||
HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
|
||||
MergeIncludedKeycodes(&included, &next_incl, op);
|
||||
ClearKeyNamesInfo(&next_incl);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->errorCount += 10; /* XXX: Why 10?? */
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haveSelf)
|
||||
*info = included;
|
||||
else
|
||||
{
|
||||
MergeIncludedKeycodes(info, &included, newMerge);
|
||||
ClearKeyNamesInfo(&included);
|
||||
}
|
||||
return (info->errorCount == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given statement and store the output in the info struct.
|
||||
* e.g. <ESC> = 9
|
||||
*/
|
||||
static int
|
||||
HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
|
||||
{
|
||||
int code;
|
||||
ExprResult result;
|
||||
|
||||
if (!ExprResolveInteger(stmt->value, &result, NULL, NULL))
|
||||
{
|
||||
ACTION1("No value keycode assigned to name <%s>\n", stmt->name);
|
||||
return 0;
|
||||
}
|
||||
code = result.ival;
|
||||
if ((code < info->effectiveMin) || (code > info->effectiveMax))
|
||||
{
|
||||
ERROR2("Illegal keycode %d for name <%s>\n", code, stmt->name);
|
||||
ACTION2("Must be in the range %d-%d inclusive\n",
|
||||
info->effectiveMin, info->effectiveMax);
|
||||
return 0;
|
||||
}
|
||||
if (stmt->merge != MergeDefault)
|
||||
{
|
||||
if (stmt->merge == MergeReplace)
|
||||
merge = MergeOverride;
|
||||
else
|
||||
merge = stmt->merge;
|
||||
}
|
||||
return AddKeyName(info, code, stmt->name, merge, info->fileID, True);
|
||||
}
|
||||
|
||||
#define MIN_KEYCODE_DEF 0
|
||||
#define MAX_KEYCODE_DEF 1
|
||||
|
||||
/**
|
||||
* Handle the minimum/maximum statement of the xkb file.
|
||||
* Sets explicitMin/Max and effectiveMin/Max of the info struct.
|
||||
*
|
||||
* @return 1 on success, 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
|
||||
{
|
||||
ExprResult tmp, field;
|
||||
ExprDef *arrayNdx;
|
||||
int which;
|
||||
|
||||
if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
|
||||
return 0; /* internal error, already reported */
|
||||
|
||||
if (tmp.str != NULL)
|
||||
{
|
||||
ERROR1("Unknown element %s encountered\n", tmp.str);
|
||||
ACTION1("Default for field %s ignored\n", field.str);
|
||||
return 0;
|
||||
}
|
||||
if (uStrCaseCmp(field.str, "minimum") == 0)
|
||||
which = MIN_KEYCODE_DEF;
|
||||
else if (uStrCaseCmp(field.str, "maximum") == 0)
|
||||
which = MAX_KEYCODE_DEF;
|
||||
else
|
||||
{
|
||||
ERROR("Unknown field encountered\n");
|
||||
ACTION1("Assigment to field %s ignored\n", field.str);
|
||||
return 0;
|
||||
}
|
||||
if (arrayNdx != NULL)
|
||||
{
|
||||
ERROR1("The %s setting is not an array\n", field.str);
|
||||
ACTION("Illegal array reference ignored\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ExprResolveInteger(stmt->value, &tmp, NULL, NULL) == 0)
|
||||
{
|
||||
ACTION1("Assignment to field %s ignored\n", field.str);
|
||||
return 0;
|
||||
}
|
||||
if ((tmp.ival < XkbMinLegalKeyCode) || (tmp.ival > XkbMaxLegalKeyCode))
|
||||
{
|
||||
ERROR3
|
||||
("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
|
||||
tmp.ival, XkbMinLegalKeyCode, XkbMaxLegalKeyCode);
|
||||
ACTION1("Value of \"%s\" not changed\n", field.str);
|
||||
return 0;
|
||||
}
|
||||
if (which == MIN_KEYCODE_DEF)
|
||||
{
|
||||
if ((info->explicitMax > 0) && (info->explicitMax < tmp.ival))
|
||||
{
|
||||
ERROR2
|
||||
("Minimum key code (%d) must be <= maximum key code (%d)\n",
|
||||
tmp.ival, info->explicitMax);
|
||||
ACTION("Minimum key code value not changed\n");
|
||||
return 0;
|
||||
}
|
||||
if ((info->computedMax > 0) && (info->computedMin < tmp.ival))
|
||||
{
|
||||
ERROR2
|
||||
("Minimum key code (%d) must be <= lowest defined key (%d)\n",
|
||||
tmp.ival, info->computedMin);
|
||||
ACTION("Minimum key code value not changed\n");
|
||||
return 0;
|
||||
}
|
||||
info->explicitMin = tmp.ival;
|
||||
info->effectiveMin = tmp.ival;
|
||||
}
|
||||
if (which == MAX_KEYCODE_DEF)
|
||||
{
|
||||
if ((info->explicitMin > 0) && (info->explicitMin > tmp.ival))
|
||||
{
|
||||
ERROR2("Maximum code (%d) must be >= minimum key code (%d)\n",
|
||||
tmp.ival, info->explicitMin);
|
||||
ACTION("Maximum code value not changed\n");
|
||||
return 0;
|
||||
}
|
||||
if ((info->computedMax > 0) && (info->computedMax > tmp.ival))
|
||||
{
|
||||
ERROR2
|
||||
("Maximum code (%d) must be >= highest defined key (%d)\n",
|
||||
tmp.ival, info->computedMax);
|
||||
ACTION("Maximum code value not changed\n");
|
||||
return 0;
|
||||
}
|
||||
info->explicitMax = tmp.ival;
|
||||
info->effectiveMax = tmp.ival;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
HandleIndicatorNameDef(IndicatorNameDef * def,
|
||||
unsigned merge, KeyNamesInfo * info)
|
||||
{
|
||||
IndicatorNameInfo ii;
|
||||
ExprResult tmp;
|
||||
|
||||
if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
|
||||
{
|
||||
info->errorCount++;
|
||||
ERROR1("Name specified for illegal indicator index %d\n", def->ndx);
|
||||
ACTION("Ignored\n");
|
||||
return False;
|
||||
}
|
||||
InitIndicatorNameInfo(&ii, info);
|
||||
ii.ndx = def->ndx;
|
||||
if (!ExprResolveString(def->name, &tmp, NULL, NULL))
|
||||
{
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%d", def->ndx);
|
||||
info->errorCount++;
|
||||
return ReportBadType("indicator", "name", buf, "string");
|
||||
}
|
||||
ii.name = XkbInternAtom(NULL, tmp.str, False);
|
||||
ii.virtual = def->virtual;
|
||||
if (!AddIndicatorName(info, &ii))
|
||||
return False;
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the xkb_keycodes section of a xkb file.
|
||||
* All information about parsed keys is stored in the info struct.
|
||||
*
|
||||
* Such a section may have include statements, in which case this function is
|
||||
* semi-recursive (it calls HandleIncludeKeycodes, which may call
|
||||
* HandleKeycodesFile again).
|
||||
*
|
||||
* @param file The input file (parsed xkb_keycodes section)
|
||||
* @param xkb Necessary to pass down, may have flags changed.
|
||||
* @param merge Merge strategy (MergeOverride, etc.)
|
||||
* @param info Struct to contain the fully parsed key information.
|
||||
*/
|
||||
static void
|
||||
HandleKeycodesFile(XkbFile * file,
|
||||
XkbDescPtr xkb, unsigned merge, KeyNamesInfo * info)
|
||||
{
|
||||
ParseCommon *stmt;
|
||||
|
||||
info->name = uStringDup(file->name);
|
||||
stmt = file->defs;
|
||||
while (stmt)
|
||||
{
|
||||
switch (stmt->stmtType)
|
||||
{
|
||||
case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
|
||||
if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtKeycodeDef: /* e.g. <ESC> = 9; */
|
||||
if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
|
||||
if (!HandleAliasDef((KeyAliasDef *) stmt,
|
||||
merge, info->fileID, &info->aliases))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtVarDef: /* e.g. minimum, maximum */
|
||||
if (!HandleKeyNameVar((VarDef *) stmt, info))
|
||||
info->errorCount++;
|
||||
break;
|
||||
case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
|
||||
if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt,
|
||||
merge, info))
|
||||
{
|
||||
info->errorCount++;
|
||||
}
|
||||
break;
|
||||
case StmtInterpDef:
|
||||
case StmtVModDef:
|
||||
ERROR("Keycode files may define key and indicator names only\n");
|
||||
ACTION1("Ignoring definition of %s\n",
|
||||
((stmt->stmtType ==
|
||||
StmtInterpDef) ? "a symbol interpretation" :
|
||||
"virtual modifiers"));
|
||||
info->errorCount++;
|
||||
break;
|
||||
default:
|
||||
WSGO1("Unexpected statement type %d in HandleKeycodesFile\n",
|
||||
stmt->stmtType);
|
||||
break;
|
||||
}
|
||||
stmt = stmt->next;
|
||||
if (info->errorCount > 10)
|
||||
{
|
||||
#ifdef NOISY
|
||||
ERROR("Too many errors\n");
|
||||
#endif
|
||||
ACTION1("Abandoning keycodes file \"%s\"\n", file->topName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the xkb_keycodes section, parse it's output, return the results.
|
||||
*
|
||||
* @param file The parsed XKB file (may have include statements requiring
|
||||
* further parsing)
|
||||
* @param result The effective keycodes, as gathered from the file.
|
||||
* @param merge Merge strategy.
|
||||
*
|
||||
* @return True on success, False otherwise.
|
||||
*/
|
||||
Bool
|
||||
CompileKeycodes(XkbFile * file, XkbFileInfo * result, unsigned merge)
|
||||
{
|
||||
KeyNamesInfo info; /* contains all the info after parsing */
|
||||
XkbDescPtr xkb;
|
||||
|
||||
xkb = result->xkb;
|
||||
InitKeyNamesInfo(&info);
|
||||
HandleKeycodesFile(file, xkb, merge, &info);
|
||||
|
||||
/* all the keys are now stored in info */
|
||||
|
||||
if (info.errorCount == 0)
|
||||
{
|
||||
if (info.explicitMin > 0) /* if "minimum" statement was present */
|
||||
xkb->min_key_code = info.effectiveMin;
|
||||
else
|
||||
xkb->min_key_code = info.computedMin;
|
||||
if (info.explicitMax > 0) /* if "maximum" statement was present */
|
||||
xkb->max_key_code = info.effectiveMax;
|
||||
else
|
||||
xkb->max_key_code = info.computedMax;
|
||||
if (XkbAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0)
|
||||
== Success)
|
||||
{
|
||||
register int i;
|
||||
xkb->names->keycodes = XkbInternAtom(xkb->dpy, info.name, False);
|
||||
uDEBUG2(1, "key range: %d..%d\n", xkb->min_key_code,
|
||||
xkb->max_key_code);
|
||||
for (i = info.computedMin; i <= info.computedMax; i++)
|
||||
{
|
||||
LongToKeyName(info.names[i], xkb->names->keys[i].name);
|
||||
uDEBUG2(2, "key %d = %s\n", i,
|
||||
XkbKeyNameText(xkb->names->keys[i].name, XkbMessage));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WSGO("Cannot create XkbNamesRec in CompileKeycodes\n");
|
||||
return False;
|
||||
}
|
||||
if (info.leds)
|
||||
{
|
||||
IndicatorNameInfo *ii;
|
||||
if (XkbAllocIndicatorMaps(xkb) != Success)
|
||||
{
|
||||
WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
|
||||
ACTION("Physical indicators not set\n");
|
||||
}
|
||||
for (ii = info.leds; ii != NULL;
|
||||
ii = (IndicatorNameInfo *) ii->defs.next)
|
||||
{
|
||||
xkb->names->indicators[ii->ndx - 1] =
|
||||
XkbInternAtom(xkb->dpy,
|
||||
XkbAtomGetString(NULL, ii->name), False);
|
||||
if (xkb->indicators != NULL)
|
||||
{
|
||||
register unsigned bit;
|
||||
bit = 1 << (ii->ndx - 1);
|
||||
if (ii->virtual)
|
||||
xkb->indicators->phys_indicators &= ~bit;
|
||||
else
|
||||
xkb->indicators->phys_indicators |= bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info.aliases)
|
||||
ApplyAliases(xkb, False, &info.aliases);
|
||||
return True;
|
||||
}
|
||||
ClearKeyNamesInfo(&info);
|
||||
return False;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef KEYCODES_H
|
||||
#define KEYCODES_H 1
|
||||
|
||||
#define KeyNameToLong(n) ((((unsigned long)n[0])<<24)|(((unsigned long)n[1])<<16)|(((unsigned long)n[2])<<8)|n[3])
|
||||
|
||||
extern char *longText(unsigned long /* val */ ,
|
||||
unsigned /* format */
|
||||
);
|
||||
|
||||
extern void LongToKeyName(unsigned long /* val */ ,
|
||||
char * /* name_rtrn */
|
||||
);
|
||||
|
||||
#endif /* KEYCODES_H */
|
|
@ -0,0 +1,183 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "tokens.h"
|
||||
#include "expr.h"
|
||||
#include "vmod.h"
|
||||
#include "action.h"
|
||||
#include "misc.h"
|
||||
#include "indicators.h"
|
||||
|
||||
#define KEYCODES 0
|
||||
#define GEOMETRY 1
|
||||
#define TYPES 2
|
||||
#define COMPAT 3
|
||||
#define SYMBOLS 4
|
||||
#define MAX_SECTIONS 5
|
||||
|
||||
static XkbFile *sections[MAX_SECTIONS];
|
||||
|
||||
/**
|
||||
* Compile the given file and store the output in result.
|
||||
* @param file A list of XkbFiles, each denoting one type (e.g.
|
||||
* XkmKeyNamesIdx, etc.)
|
||||
*/
|
||||
Bool
|
||||
CompileKeymap(XkbFile * file, XkbFileInfo * result, unsigned merge)
|
||||
{
|
||||
unsigned have;
|
||||
Bool ok;
|
||||
unsigned required, legal;
|
||||
unsigned mainType;
|
||||
char *mainName;
|
||||
LEDInfo *unbound = NULL;
|
||||
|
||||
bzero(sections, MAX_SECTIONS * sizeof(XkbFile *));
|
||||
mainType = file->type;
|
||||
mainName = file->name;
|
||||
switch (mainType)
|
||||
{
|
||||
case XkmSemanticsFile:
|
||||
required = XkmSemanticsRequired;
|
||||
legal = XkmSemanticsLegal;
|
||||
break;
|
||||
case XkmLayoutFile: /* standard type if setxkbmap -print */
|
||||
required = XkmLayoutRequired;
|
||||
legal = XkmKeymapLegal;
|
||||
break;
|
||||
case XkmKeymapFile:
|
||||
required = XkmKeymapRequired;
|
||||
legal = XkmKeymapLegal;
|
||||
break;
|
||||
default:
|
||||
ERROR1("Cannot compile %s alone into an XKM file\n",
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
return False;
|
||||
}
|
||||
have = 0;
|
||||
ok = 1;
|
||||
file = (XkbFile *) file->defs;
|
||||
/* Check for duplicate entries in the input file */
|
||||
while ((file) && (ok))
|
||||
{
|
||||
file->topName = mainName;
|
||||
if ((have & (1 << file->type)) != 0)
|
||||
{
|
||||
ERROR2("More than one %s section in a %s file\n",
|
||||
XkbConfigText(file->type, XkbMessage),
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
ACTION("All sections after the first ignored\n");
|
||||
ok = False;
|
||||
}
|
||||
else if ((1 << file->type) & (~legal))
|
||||
{
|
||||
ERROR2("Cannot define %s in a %s file\n",
|
||||
XkbConfigText(file->type, XkbMessage),
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
ok = False;
|
||||
}
|
||||
else
|
||||
switch (file->type)
|
||||
{
|
||||
case XkmSemanticsFile:
|
||||
case XkmLayoutFile:
|
||||
case XkmKeymapFile:
|
||||
WSGO2("Illegal %s configuration in a %s file\n",
|
||||
XkbConfigText(file->type, XkbMessage),
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
ACTION("Ignored\n");
|
||||
ok = False;
|
||||
break;
|
||||
case XkmKeyNamesIndex:
|
||||
sections[KEYCODES] = file;
|
||||
break;
|
||||
case XkmTypesIndex:
|
||||
sections[TYPES] = file;
|
||||
break;
|
||||
case XkmSymbolsIndex:
|
||||
sections[SYMBOLS] = file;
|
||||
break;
|
||||
case XkmCompatMapIndex:
|
||||
sections[COMPAT] = file;
|
||||
break;
|
||||
case XkmGeometryIndex:
|
||||
case XkmGeometryFile:
|
||||
sections[GEOMETRY] = file;
|
||||
break;
|
||||
case XkmVirtualModsIndex:
|
||||
case XkmIndicatorsIndex:
|
||||
WSGO1("Found an isolated %s section\n",
|
||||
XkbConfigText(file->type, XkbMessage));
|
||||
break;
|
||||
default:
|
||||
WSGO1("Unknown file type %d\n", file->type);
|
||||
break;
|
||||
}
|
||||
if (ok)
|
||||
have |= (1 << file->type);
|
||||
file = (XkbFile *) file->common.next;
|
||||
}
|
||||
/* compile the sections we have in the file one-by-one, or fail. */
|
||||
if (ok)
|
||||
{
|
||||
if (ok && (sections[KEYCODES] != NULL))
|
||||
ok = CompileKeycodes(sections[KEYCODES], result, MergeOverride);
|
||||
if (ok && (sections[GEOMETRY] != NULL))
|
||||
ok = CompileGeometry(sections[GEOMETRY], result, MergeOverride);
|
||||
if (ok && (sections[TYPES] != NULL))
|
||||
ok = CompileKeyTypes(sections[TYPES], result, MergeOverride);
|
||||
if (ok && (sections[COMPAT] != NULL))
|
||||
ok = CompileCompatMap(sections[COMPAT], result, MergeOverride,
|
||||
&unbound);
|
||||
if (ok && (sections[SYMBOLS] != NULL))
|
||||
ok = CompileSymbols(sections[SYMBOLS], result, MergeOverride);
|
||||
}
|
||||
if (!ok)
|
||||
return False;
|
||||
result->defined = have;
|
||||
if (required & (~have))
|
||||
{
|
||||
register int i, bit;
|
||||
unsigned missing;
|
||||
missing = required & (~have);
|
||||
for (i = 0, bit = 1; missing != 0; i++, bit <<= 1)
|
||||
{
|
||||
if (missing & bit)
|
||||
{
|
||||
ERROR2("Missing %s section in a %s file\n",
|
||||
XkbConfigText(i, XkbMessage),
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
missing &= ~bit;
|
||||
}
|
||||
}
|
||||
ACTION1("Description of %s not compiled\n",
|
||||
XkbConfigText(mainType, XkbMessage));
|
||||
ok = False;
|
||||
}
|
||||
ok = BindIndicators(result, True, unbound, NULL);
|
||||
return ok;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,495 @@
|
|||
/************************************************************
|
||||
Copyright 1996 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1988, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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 Open Group 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 Open Group.
|
||||
|
||||
|
||||
Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#if defined(sgi)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG_VAR listingDebug
|
||||
#include "xkbcomp.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
# include <limits.h>
|
||||
#else
|
||||
# define _POSIX_SOURCE
|
||||
# include <limits.h>
|
||||
# undef _POSIX_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifdef WIN32
|
||||
#define PATH_MAX 512
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#ifndef PATH_MAX
|
||||
#ifdef MAXPATHLEN
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#else
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
# define FileName(file) file.cFileName
|
||||
# undef TEXT
|
||||
# undef ALTERNATE
|
||||
#else
|
||||
# include <dirent.h>
|
||||
# define FileName(file) file->d_name
|
||||
#endif
|
||||
|
||||
#include "xkbpath.h"
|
||||
#include "parseutils.h"
|
||||
#include "misc.h"
|
||||
#include "tokens.h"
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
|
||||
#define lowbit(x) ((x) & (-(x)))
|
||||
|
||||
unsigned int listingDebug;
|
||||
|
||||
static int szListing = 0;
|
||||
static int nListed = 0;
|
||||
static int nFilesListed = 0;
|
||||
|
||||
typedef struct _Listing
|
||||
{
|
||||
char *file;
|
||||
char *map;
|
||||
} Listing;
|
||||
|
||||
static int szMapOnly;
|
||||
static int nMapOnly;
|
||||
static char **mapOnly;
|
||||
|
||||
static Listing *list = NULL;
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
int
|
||||
AddMapOnly(char *map)
|
||||
{
|
||||
if (nMapOnly >= szMapOnly)
|
||||
{
|
||||
if (szMapOnly < 1)
|
||||
szMapOnly = 5;
|
||||
else
|
||||
szMapOnly *= 2;
|
||||
mapOnly = uTypedRealloc(list, szMapOnly, char *);
|
||||
if (!mapOnly)
|
||||
{
|
||||
WSGO("Couldn't allocate list of maps\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mapOnly[nMapOnly++] = map;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
AddListing(char *file, char *map)
|
||||
{
|
||||
if (nListed >= szListing)
|
||||
{
|
||||
if (szListing < 1)
|
||||
szListing = 10;
|
||||
else
|
||||
szListing *= 2;
|
||||
list = uTypedRealloc(list, szListing, Listing);
|
||||
if (!list)
|
||||
{
|
||||
WSGO("Couldn't allocate list of files and maps\n");
|
||||
ACTION("Exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
list[nListed].file = file;
|
||||
list[nListed].map = map;
|
||||
nListed++;
|
||||
if (file != NULL)
|
||||
nFilesListed++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
ListFile(FILE * outFile, char *fileName, XkbFile * map)
|
||||
{
|
||||
register unsigned flags;
|
||||
char *mapName;
|
||||
|
||||
flags = map->flags;
|
||||
if ((flags & XkbLC_Hidden) && (!(verboseLevel & WantHiddenMaps)))
|
||||
return;
|
||||
if ((flags & XkbLC_Partial) && (!(verboseLevel & WantPartialMaps)))
|
||||
return;
|
||||
if (verboseLevel & WantLongListing)
|
||||
{
|
||||
fprintf(outFile, (flags & XkbLC_Hidden) ? "h" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_Default) ? "d" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_Partial) ? "p" : "-");
|
||||
fprintf(outFile, "----- ");
|
||||
if (map->type == XkmSymbolsIndex)
|
||||
{
|
||||
fprintf(outFile, (flags & XkbLC_AlphanumericKeys) ? "a" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_ModifierKeys) ? "m" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_KeypadKeys) ? "k" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_FunctionKeys) ? "f" : "-");
|
||||
fprintf(outFile, (flags & XkbLC_AlternateGroup) ? "g" : "-");
|
||||
fprintf(outFile, "--- ");
|
||||
}
|
||||
else
|
||||
fprintf(outFile, "-------- ");
|
||||
}
|
||||
mapName = map->name;
|
||||
if ((!(verboseLevel & WantFullNames)) && ((flags & XkbLC_Default) != 0))
|
||||
mapName = NULL;
|
||||
if (dirsToStrip > 0)
|
||||
{
|
||||
char *tmp, *last;
|
||||
int i;
|
||||
for (i = 0, tmp = last = fileName; (i < dirsToStrip) && tmp; i++)
|
||||
{
|
||||
last = tmp;
|
||||
tmp = strchr(tmp, '/');
|
||||
if (tmp != NULL)
|
||||
tmp++;
|
||||
}
|
||||
fileName = (tmp ? tmp : last);
|
||||
}
|
||||
if (mapName)
|
||||
fprintf(outFile, "%s(%s)\n", fileName, mapName);
|
||||
else
|
||||
fprintf(outFile, "%s\n", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static int
|
||||
AddDirectory(char *head, char *ptrn, char *rest, char *map)
|
||||
{
|
||||
#ifdef WIN32
|
||||
HANDLE dirh;
|
||||
WIN32_FIND_DATA file;
|
||||
#else
|
||||
DIR *dirp;
|
||||
struct dirent *file;
|
||||
#endif
|
||||
int nMatch;
|
||||
|
||||
if (map == NULL)
|
||||
{
|
||||
char *tmp = ptrn;
|
||||
if ((rest == NULL) && (ptrn != NULL) && (strchr(ptrn, '/') == NULL))
|
||||
{
|
||||
tmp = ptrn;
|
||||
map = strchr(ptrn, '(');
|
||||
}
|
||||
else if ((rest == NULL) && (ptrn == NULL) &&
|
||||
(head != NULL) && (strchr(head, '/') == NULL))
|
||||
{
|
||||
tmp = head;
|
||||
map = strchr(head, '(');
|
||||
}
|
||||
if (map != NULL)
|
||||
{
|
||||
tmp = strchr(tmp, ')');
|
||||
if ((tmp == NULL) || (tmp[1] != '\0'))
|
||||
{
|
||||
ERROR1("File and map must have the format file(map)\n");
|
||||
return 0;
|
||||
}
|
||||
*map = '\0';
|
||||
map++;
|
||||
*tmp = '\0';
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
if ((dirh = FindFirstFile("*.*", &file)) == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
#else
|
||||
if ((dirp = opendir((head ? head : "."))) == NULL)
|
||||
return 0;
|
||||
nMatch = 0;
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
do
|
||||
#else
|
||||
while ((file = readdir(dirp)) != NULL)
|
||||
#endif
|
||||
{
|
||||
char *tmp, *filename;
|
||||
struct stat sbuf;
|
||||
|
||||
filename = FileName(file);
|
||||
if (!filename || filename[0] == '.')
|
||||
continue;
|
||||
if (ptrn && (!XkbNameMatchesPattern(filename, ptrn)))
|
||||
continue;
|
||||
tmp =
|
||||
(char *) uAlloc((head ? strlen(head) : 0) + strlen(filename) + 2);
|
||||
if (!tmp)
|
||||
continue;
|
||||
sprintf(tmp, "%s%s%s", (head ? head : ""), (head ? "/" : ""),
|
||||
filename);
|
||||
if (stat(tmp, &sbuf) < 0)
|
||||
{
|
||||
uFree(tmp);
|
||||
continue;
|
||||
}
|
||||
if (((rest != NULL) && (!S_ISDIR(sbuf.st_mode))) ||
|
||||
((map != NULL) && (S_ISDIR(sbuf.st_mode))))
|
||||
{
|
||||
uFree(tmp);
|
||||
continue;
|
||||
}
|
||||
if (S_ISDIR(sbuf.st_mode))
|
||||
{
|
||||
if ((rest != NULL) || (verboseLevel & ListRecursive))
|
||||
nMatch += AddDirectory(tmp, rest, NULL, map);
|
||||
}
|
||||
else
|
||||
nMatch += AddListing(tmp, map);
|
||||
}
|
||||
#ifdef WIN32
|
||||
while (FindNextFile(dirh, &file));
|
||||
#endif
|
||||
return nMatch;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Bool
|
||||
AddMatchingFiles(char *head_in)
|
||||
{
|
||||
char *str, *head, *ptrn, *rest = NULL;
|
||||
|
||||
if (head_in == NULL)
|
||||
return 0;
|
||||
ptrn = NULL;
|
||||
for (str = head_in; (*str != '\0') && (*str != '?') && (*str != '*');
|
||||
str++)
|
||||
{
|
||||
if ((str != head_in) && (*str == '/'))
|
||||
ptrn = str;
|
||||
}
|
||||
if (*str == '\0')
|
||||
{ /* no wildcards */
|
||||
head = head_in;
|
||||
ptrn = NULL;
|
||||
rest = NULL;
|
||||
}
|
||||
else if (ptrn == NULL)
|
||||
{ /* no slash before the first wildcard */
|
||||
head = NULL;
|
||||
ptrn = head_in;
|
||||
}
|
||||
else
|
||||
{ /* slash followed by wildcard */
|
||||
head = head_in;
|
||||
*ptrn = '\0';
|
||||
ptrn++;
|
||||
}
|
||||
if (ptrn)
|
||||
{
|
||||
rest = strchr(ptrn, '/');
|
||||
if (rest != NULL)
|
||||
{
|
||||
*rest = '\0';
|
||||
rest++;
|
||||
}
|
||||
}
|
||||
if (((rest && ptrn)
|
||||
&& ((strchr(ptrn, '(') != NULL) || (strchr(ptrn, ')') != NULL)))
|
||||
|| (head
|
||||
&& ((strchr(head, '(') != NULL) || (strchr(head, ')') != NULL))))
|
||||
{
|
||||
ERROR1("Files/maps to list must have the form file(map)\n");
|
||||
ACTION("Illegal specifier ignored\n");
|
||||
return 0;
|
||||
}
|
||||
return AddDirectory(head, ptrn, rest, NULL);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static Bool
|
||||
MapMatches(char *mapToConsider, char *ptrn)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ptrn != NULL)
|
||||
return XkbNameMatchesPattern(mapToConsider, ptrn);
|
||||
if (nMapOnly < 1)
|
||||
return True;
|
||||
for (i = 0; i < nMapOnly; i++)
|
||||
{
|
||||
if (XkbNameMatchesPattern(mapToConsider, mapOnly[i]))
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
GenerateListing(char *out_name)
|
||||
{
|
||||
int i;
|
||||
FILE *inputFile, *outFile;
|
||||
XkbFile *rtrn, *mapToUse;
|
||||
unsigned oldWarningLevel;
|
||||
char *mapName;
|
||||
|
||||
if (nFilesListed < 1)
|
||||
{
|
||||
ERROR1("Must specify at least one file or pattern to list\n");
|
||||
return 0;
|
||||
}
|
||||
if ((!out_name) || ((out_name[0] == '-') && (out_name[1] == '\0')))
|
||||
outFile = stdout;
|
||||
else if ((outFile = fopen(out_name, "w")) == NULL)
|
||||
{
|
||||
ERROR1("Cannot open \"%s\" to write keyboard description\n",
|
||||
out_name);
|
||||
ACTION("Exiting\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (warningLevel > 9)
|
||||
fprintf(stderr, "should list:\n");
|
||||
#endif
|
||||
for (i = 0; i < nListed; i++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (warningLevel > 9)
|
||||
{
|
||||
fprintf(stderr, "%s(%s)\n",
|
||||
(list[i].file ? list[i].file : "*"),
|
||||
(list[i].map ? list[i].map : "*"));
|
||||
}
|
||||
#endif
|
||||
oldWarningLevel = warningLevel;
|
||||
warningLevel = 0;
|
||||
if (list[i].file)
|
||||
{
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat(list[i].file, &sbuf) < 0)
|
||||
{
|
||||
if (oldWarningLevel > 5)
|
||||
WARN1("Couldn't open \"%s\"\n", list[i].file);
|
||||
continue;
|
||||
}
|
||||
if (S_ISDIR(sbuf.st_mode))
|
||||
{
|
||||
if (verboseLevel & ListRecursive)
|
||||
AddDirectory(list[i].file, NULL, NULL, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
inputFile = fopen(list[i].file, "r");
|
||||
if (!inputFile)
|
||||
{
|
||||
if (oldWarningLevel > 5)
|
||||
WARN1("Couldn't open \"%s\"\n", list[i].file);
|
||||
continue;
|
||||
}
|
||||
setScanState(list[i].file, 1);
|
||||
if (XKBParseFile(inputFile, &rtrn) && (rtrn != NULL))
|
||||
{
|
||||
mapName = list[i].map;
|
||||
mapToUse = rtrn;
|
||||
for (; mapToUse; mapToUse = (XkbFile *) mapToUse->common.next)
|
||||
{
|
||||
if (!MapMatches(mapToUse->name, mapName))
|
||||
continue;
|
||||
ListFile(outFile, list[i].file, mapToUse);
|
||||
}
|
||||
}
|
||||
fclose(inputFile);
|
||||
}
|
||||
warningLevel = oldWarningLevel;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,576 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "xkbpath.h"
|
||||
#include "tokens.h"
|
||||
#include "keycodes.h"
|
||||
#include "misc.h"
|
||||
#include <X11/keysym.h>
|
||||
#include "parseutils.h"
|
||||
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
/**
|
||||
* Open the file given in the include statement and parse it's content.
|
||||
* If the statement defines a specific map to use, this map is returned in
|
||||
* file_rtrn. Otherwise, the default map is returned.
|
||||
*
|
||||
* @param stmt The include statement, specifying the file name to look for.
|
||||
* @param file_type Type of file (XkmKeyNamesIdx, etc.)
|
||||
* @param file_rtrn Returns the key map to be used.
|
||||
* @param merge_rtrn Always returns stmt->merge.
|
||||
*
|
||||
* @return True on success or False otherwise.
|
||||
*/
|
||||
Bool
|
||||
ProcessIncludeFile(IncludeStmt * stmt,
|
||||
unsigned file_type,
|
||||
XkbFile ** file_rtrn, unsigned *merge_rtrn)
|
||||
{
|
||||
FILE *file;
|
||||
XkbFile *rtrn, *mapToUse;
|
||||
char oldFile[1024] = {0};
|
||||
int oldLine = lineNum;
|
||||
|
||||
rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path);
|
||||
if (rtrn == NULL)
|
||||
{
|
||||
/* file not in cache, open it, parse it and store it in cache for next
|
||||
time. */
|
||||
file = XkbFindFileInPath(stmt->file, file_type, &stmt->path);
|
||||
if (file == NULL)
|
||||
{
|
||||
ERROR2("Can't find file \"%s\" for %s include\n", stmt->file,
|
||||
XkbDirectoryForInclude(file_type));
|
||||
ACTION("Exiting\n");
|
||||
return False;
|
||||
}
|
||||
strcpy(oldFile, scanFile);
|
||||
oldLine = lineNum;
|
||||
setScanState(stmt->file, 1);
|
||||
if (debugFlags & 2)
|
||||
INFO1("About to parse include file %s\n", stmt->file);
|
||||
/* parse the file */
|
||||
if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
|
||||
{
|
||||
setScanState(oldFile, oldLine);
|
||||
ERROR1("Error interpreting include file \"%s\"\n", stmt->file);
|
||||
ACTION("Exiting\n");
|
||||
fclose(file);
|
||||
return False;
|
||||
}
|
||||
fclose(file);
|
||||
XkbAddFileToCache(stmt->file, file_type, stmt->path, rtrn);
|
||||
}
|
||||
mapToUse = rtrn;
|
||||
if (stmt->map != NULL)
|
||||
{
|
||||
while ((mapToUse) && ((!uStringEqual(mapToUse->name, stmt->map)) ||
|
||||
(mapToUse->type != file_type)))
|
||||
{
|
||||
mapToUse = (XkbFile *) mapToUse->common.next;
|
||||
}
|
||||
if (!mapToUse)
|
||||
{
|
||||
ERROR3("No %s named \"%s\" in the include file \"%s\"\n",
|
||||
XkbConfigText(file_type, XkbMessage), stmt->map,
|
||||
stmt->file);
|
||||
ACTION("Exiting\n");
|
||||
return False;
|
||||
}
|
||||
}
|
||||
else if ((rtrn->common.next != NULL) && (warningLevel > 5))
|
||||
{
|
||||
WARN1("No map in include statement, but \"%s\" contains several\n",
|
||||
stmt->file);
|
||||
ACTION1("Using first defined map, \"%s\"\n", rtrn->name);
|
||||
}
|
||||
setScanState(oldFile, oldLine);
|
||||
if (mapToUse->type != file_type)
|
||||
{
|
||||
ERROR2("Include file wrong type (expected %s, got %s)\n",
|
||||
XkbConfigText(file_type, XkbMessage),
|
||||
XkbConfigText(mapToUse->type, XkbMessage));
|
||||
ACTION1("Include file \"%s\" ignored\n", stmt->file);
|
||||
return False;
|
||||
}
|
||||
/* FIXME: we have to check recursive includes here (or somewhere) */
|
||||
|
||||
mapToUse->compiled = True;
|
||||
*file_rtrn = mapToUse;
|
||||
*merge_rtrn = stmt->merge;
|
||||
return True;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
int
|
||||
ReportNotArray(const char *type, const char *field, const char *name)
|
||||
{
|
||||
ERROR2("The %s %s field is not an array\n", type, field);
|
||||
ACTION1("Ignoring illegal assignment in %s\n", name);
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
ReportShouldBeArray(const char *type, const char *field, char *name)
|
||||
{
|
||||
ERROR2("Missing subscript for %s %s\n", type, field);
|
||||
ACTION1("Ignoring illegal assignment in %s\n", name);
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
ReportBadType(const char *type, const char *field,
|
||||
const char *name, const char *wanted)
|
||||
{
|
||||
ERROR3("The %s %s field must be a %s\n", type, field, wanted);
|
||||
ACTION1("Ignoring illegal assignment in %s\n", name);
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
ReportBadIndexType(char *type, char *field, char *name, char *wanted)
|
||||
{
|
||||
ERROR3("Index for the %s %s field must be a %s\n", type, field, wanted);
|
||||
ACTION1("Ignoring assignment to illegal field in %s\n", name);
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
ReportBadField(const char *type, const char *field, const char *name)
|
||||
{
|
||||
ERROR3("Unknown %s field %s in %s\n", type, field, name);
|
||||
ACTION1("Ignoring assignment to unknown field in %s\n", name);
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
ReportMultipleDefs(char *type, char *field, char *name)
|
||||
{
|
||||
WARN3("Multiple definitions of %s in %s \"%s\"\n", field, type, name);
|
||||
ACTION("Using last definition\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Bool
|
||||
UseNewField(unsigned field,
|
||||
CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
|
||||
{
|
||||
Bool useNew;
|
||||
|
||||
useNew = False;
|
||||
if (oldDefs->defined & field)
|
||||
{
|
||||
if (newDefs->defined & field)
|
||||
{
|
||||
if (((oldDefs->fileID == newDefs->fileID)
|
||||
&& (warningLevel > 0)) || (warningLevel > 9))
|
||||
{
|
||||
*pCollide |= field;
|
||||
}
|
||||
if (newDefs->merge != MergeAugment)
|
||||
useNew = True;
|
||||
}
|
||||
}
|
||||
else if (newDefs->defined & field)
|
||||
useNew = True;
|
||||
return useNew;
|
||||
}
|
||||
|
||||
Bool
|
||||
MergeNewField(unsigned field,
|
||||
CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
|
||||
{
|
||||
if ((oldDefs->defined & field) && (newDefs->defined & field))
|
||||
{
|
||||
if (((oldDefs->fileID == newDefs->fileID) && (warningLevel > 0)) ||
|
||||
(warningLevel > 9))
|
||||
{
|
||||
*pCollide |= field;
|
||||
}
|
||||
if (newDefs->merge == MergeAugment)
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
XPointer
|
||||
ClearCommonInfo(CommonInfo * cmn)
|
||||
{
|
||||
if (cmn != NULL)
|
||||
{
|
||||
CommonInfo *this, *next;
|
||||
for (this = cmn; this != NULL; this = next)
|
||||
{
|
||||
next = this->next;
|
||||
uFree(this);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XPointer
|
||||
AddCommonInfo(CommonInfo * old, CommonInfo * new)
|
||||
{
|
||||
CommonInfo *first;
|
||||
|
||||
first = old;
|
||||
while (old && old->next)
|
||||
{
|
||||
old = old->next;
|
||||
}
|
||||
new->next = NULL;
|
||||
if (old)
|
||||
{
|
||||
old->next = new;
|
||||
return (XPointer) first;
|
||||
}
|
||||
return (XPointer) new;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
typedef struct _KeyNameDesc
|
||||
{
|
||||
KeySym level1;
|
||||
KeySym level2;
|
||||
char name[5];
|
||||
Bool used;
|
||||
} KeyNameDesc;
|
||||
|
||||
static KeyNameDesc dfltKeys[] = {
|
||||
{XK_Escape, NoSymbol, "ESC\0"},
|
||||
{XK_quoteleft, XK_asciitilde, "TLDE"},
|
||||
{XK_1, XK_exclam, "AE01"},
|
||||
{XK_2, XK_at, "AE02"},
|
||||
{XK_3, XK_numbersign, "AE03"},
|
||||
{XK_4, XK_dollar, "AE04"},
|
||||
{XK_5, XK_percent, "AE05"},
|
||||
{XK_6, XK_asciicircum, "AE06"},
|
||||
{XK_7, XK_ampersand, "AE07"},
|
||||
{XK_8, XK_asterisk, "AE08"},
|
||||
{XK_9, XK_parenleft, "AE09"},
|
||||
{XK_0, XK_parenright, "AE10"},
|
||||
{XK_minus, XK_underscore, "AE11"},
|
||||
{XK_equal, XK_plus, "AE12"},
|
||||
{XK_BackSpace, NoSymbol, "BKSP"},
|
||||
{XK_Tab, NoSymbol, "TAB\0"},
|
||||
{XK_q, XK_Q, "AD01"},
|
||||
{XK_w, XK_W, "AD02"},
|
||||
{XK_e, XK_E, "AD03"},
|
||||
{XK_r, XK_R, "AD04"},
|
||||
{XK_t, XK_T, "AD05"},
|
||||
{XK_y, XK_Y, "AD06"},
|
||||
{XK_u, XK_U, "AD07"},
|
||||
{XK_i, XK_I, "AD08"},
|
||||
{XK_o, XK_O, "AD09"},
|
||||
{XK_p, XK_P, "AD10"},
|
||||
{XK_bracketleft, XK_braceleft, "AD11"},
|
||||
{XK_bracketright, XK_braceright, "AD12"},
|
||||
{XK_Return, NoSymbol, "RTRN"},
|
||||
{XK_Caps_Lock, NoSymbol, "CAPS"},
|
||||
{XK_a, XK_A, "AC01"},
|
||||
{XK_s, XK_S, "AC02"},
|
||||
{XK_d, XK_D, "AC03"},
|
||||
{XK_f, XK_F, "AC04"},
|
||||
{XK_g, XK_G, "AC05"},
|
||||
{XK_h, XK_H, "AC06"},
|
||||
{XK_j, XK_J, "AC07"},
|
||||
{XK_k, XK_K, "AC08"},
|
||||
{XK_l, XK_L, "AC09"},
|
||||
{XK_semicolon, XK_colon, "AC10"},
|
||||
{XK_quoteright, XK_quotedbl, "AC11"},
|
||||
{XK_Shift_L, NoSymbol, "LFSH"},
|
||||
{XK_z, XK_Z, "AB01"},
|
||||
{XK_x, XK_X, "AB02"},
|
||||
{XK_c, XK_C, "AB03"},
|
||||
{XK_v, XK_V, "AB04"},
|
||||
{XK_b, XK_B, "AB05"},
|
||||
{XK_n, XK_N, "AB06"},
|
||||
{XK_m, XK_M, "AB07"},
|
||||
{XK_comma, XK_less, "AB08"},
|
||||
{XK_period, XK_greater, "AB09"},
|
||||
{XK_slash, XK_question, "AB10"},
|
||||
{XK_backslash, XK_bar, "BKSL"},
|
||||
{XK_Control_L, NoSymbol, "LCTL"},
|
||||
{XK_space, NoSymbol, "SPCE"},
|
||||
{XK_Shift_R, NoSymbol, "RTSH"},
|
||||
{XK_Alt_L, NoSymbol, "LALT"},
|
||||
{XK_space, NoSymbol, "SPCE"},
|
||||
{XK_Control_R, NoSymbol, "RCTL"},
|
||||
{XK_Alt_R, NoSymbol, "RALT"},
|
||||
{XK_F1, NoSymbol, "FK01"},
|
||||
{XK_F2, NoSymbol, "FK02"},
|
||||
{XK_F3, NoSymbol, "FK03"},
|
||||
{XK_F4, NoSymbol, "FK04"},
|
||||
{XK_F5, NoSymbol, "FK05"},
|
||||
{XK_F6, NoSymbol, "FK06"},
|
||||
{XK_F7, NoSymbol, "FK07"},
|
||||
{XK_F8, NoSymbol, "FK08"},
|
||||
{XK_F9, NoSymbol, "FK09"},
|
||||
{XK_F10, NoSymbol, "FK10"},
|
||||
{XK_F11, NoSymbol, "FK11"},
|
||||
{XK_F12, NoSymbol, "FK12"},
|
||||
{XK_Print, NoSymbol, "PRSC"},
|
||||
{XK_Scroll_Lock, NoSymbol, "SCLK"},
|
||||
{XK_Pause, NoSymbol, "PAUS"},
|
||||
{XK_Insert, NoSymbol, "INS\0"},
|
||||
{XK_Home, NoSymbol, "HOME"},
|
||||
{XK_Prior, NoSymbol, "PGUP"},
|
||||
{XK_Delete, NoSymbol, "DELE"},
|
||||
{XK_End, NoSymbol, "END"},
|
||||
{XK_Next, NoSymbol, "PGDN"},
|
||||
{XK_Up, NoSymbol, "UP\0\0"},
|
||||
{XK_Left, NoSymbol, "LEFT"},
|
||||
{XK_Down, NoSymbol, "DOWN"},
|
||||
{XK_Right, NoSymbol, "RGHT"},
|
||||
{XK_Num_Lock, NoSymbol, "NMLK"},
|
||||
{XK_KP_Divide, NoSymbol, "KPDV"},
|
||||
{XK_KP_Multiply, NoSymbol, "KPMU"},
|
||||
{XK_KP_Subtract, NoSymbol, "KPSU"},
|
||||
{NoSymbol, XK_KP_7, "KP7\0"},
|
||||
{NoSymbol, XK_KP_8, "KP8\0"},
|
||||
{NoSymbol, XK_KP_9, "KP9\0"},
|
||||
{XK_KP_Add, NoSymbol, "KPAD"},
|
||||
{NoSymbol, XK_KP_4, "KP4\0"},
|
||||
{NoSymbol, XK_KP_5, "KP5\0"},
|
||||
{NoSymbol, XK_KP_6, "KP6\0"},
|
||||
{NoSymbol, XK_KP_1, "KP1\0"},
|
||||
{NoSymbol, XK_KP_2, "KP2\0"},
|
||||
{NoSymbol, XK_KP_3, "KP3\0"},
|
||||
{XK_KP_Enter, NoSymbol, "KPEN"},
|
||||
{NoSymbol, XK_KP_0, "KP0\0"},
|
||||
{XK_KP_Delete, NoSymbol, "KPDL"},
|
||||
{XK_less, XK_greater, "LSGT"},
|
||||
{XK_KP_Separator, NoSymbol, "KPCO"},
|
||||
{XK_Find, NoSymbol, "FIND"},
|
||||
{NoSymbol, NoSymbol, "\0\0\0\0"}
|
||||
};
|
||||
|
||||
Status
|
||||
ComputeKbdDefaults(XkbDescPtr xkb)
|
||||
{
|
||||
Status rtrn;
|
||||
register int i, tmp, nUnknown;
|
||||
KeyNameDesc *name;
|
||||
KeySym *syms;
|
||||
|
||||
if ((xkb->names == NULL) || (xkb->names->keys == NULL))
|
||||
{
|
||||
if ((rtrn = XkbAllocNames(xkb, XkbKeyNamesMask, 0, 0)) != Success)
|
||||
return rtrn;
|
||||
}
|
||||
for (name = dfltKeys; (name->name[0] != '\0'); name++)
|
||||
{
|
||||
name->used = False;
|
||||
}
|
||||
nUnknown = 0;
|
||||
for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
|
||||
{
|
||||
tmp = XkbKeyNumSyms(xkb, i);
|
||||
if ((xkb->names->keys[i].name[0] == '\0') && (tmp > 0))
|
||||
{
|
||||
tmp = XkbKeyGroupsWidth(xkb, i);
|
||||
syms = XkbKeySymsPtr(xkb, i);
|
||||
for (name = dfltKeys; (name->name[0] != '\0'); name++)
|
||||
{
|
||||
Bool match = True;
|
||||
if (((name->level1 != syms[0])
|
||||
&& (name->level1 != NoSymbol))
|
||||
|| ((name->level2 != NoSymbol) && (tmp < 2))
|
||||
|| ((name->level2 != syms[1])
|
||||
&& (name->level2 != NoSymbol)))
|
||||
{
|
||||
match = False;
|
||||
}
|
||||
if (match)
|
||||
{
|
||||
if (!name->used)
|
||||
{
|
||||
memcpy(xkb->names->keys[i].name, name->name,
|
||||
XkbKeyNameLength);
|
||||
name->used = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (warningLevel > 2)
|
||||
{
|
||||
WARN1
|
||||
("Several keys match pattern for %s\n",
|
||||
XkbKeyNameText(name->name, XkbMessage));
|
||||
ACTION2("Using <U%03d> for key %d\n",
|
||||
nUnknown, i);
|
||||
}
|
||||
sprintf(xkb->names->keys[i].name, "U%03d",
|
||||
nUnknown++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (xkb->names->keys[i].name[0] == '\0')
|
||||
{
|
||||
if (warningLevel > 2)
|
||||
{
|
||||
WARN1("Key %d does not match any defaults\n", i);
|
||||
ACTION1("Using name <U%03d>\n", nUnknown);
|
||||
sprintf(xkb->names->keys[i].name, "U%03d", nUnknown++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the key with the given name and return its keycode in kc_rtrn.
|
||||
*
|
||||
* @param name The 4-letter name of the key as a long.
|
||||
* @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
|
||||
* @param use_aliases True if the key aliases should be searched too.
|
||||
* @param create If True and the key is not found, it is added to the
|
||||
* xkb->names at the first free keycode.
|
||||
* @param start_from Keycode to start searching from.
|
||||
*
|
||||
* @return True if found, False otherwise.
|
||||
*/
|
||||
Bool
|
||||
FindNamedKey(XkbDescPtr xkb,
|
||||
unsigned long name,
|
||||
unsigned int *kc_rtrn,
|
||||
Bool use_aliases, Bool create, int start_from)
|
||||
{
|
||||
register unsigned n;
|
||||
|
||||
if (start_from < xkb->min_key_code)
|
||||
{
|
||||
start_from = xkb->min_key_code;
|
||||
}
|
||||
else if (start_from > xkb->max_key_code)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
*kc_rtrn = 0; /* some callers rely on this */
|
||||
if (xkb && xkb->names && xkb->names->keys)
|
||||
{
|
||||
for (n = start_from; n <= xkb->max_key_code; n++)
|
||||
{
|
||||
unsigned long tmp;
|
||||
tmp = KeyNameToLong(xkb->names->keys[n].name);
|
||||
if (tmp == name)
|
||||
{
|
||||
*kc_rtrn = n;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
if (use_aliases)
|
||||
{
|
||||
unsigned long new_name;
|
||||
if (FindKeyNameForAlias(xkb, name, &new_name))
|
||||
return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
|
||||
}
|
||||
}
|
||||
if (create)
|
||||
{
|
||||
if ((!xkb->names) || (!xkb->names->keys))
|
||||
{
|
||||
if (xkb->min_key_code < XkbMinLegalKeyCode)
|
||||
{
|
||||
xkb->min_key_code = XkbMinLegalKeyCode;
|
||||
xkb->max_key_code = XkbMaxLegalKeyCode;
|
||||
}
|
||||
if (XkbAllocNames(xkb, XkbKeyNamesMask, 0, 0) != Success)
|
||||
{
|
||||
if (warningLevel > 0)
|
||||
{
|
||||
WARN("Couldn't allocate key names in FindNamedKey\n");
|
||||
ACTION1("Key \"%s\" not automatically created\n",
|
||||
longText(name, XkbMessage));
|
||||
}
|
||||
return False;
|
||||
}
|
||||
}
|
||||
/* Find first unused keycode and store our key here */
|
||||
for (n = xkb->min_key_code; n <= xkb->max_key_code; n++)
|
||||
{
|
||||
if (xkb->names->keys[n].name[0] == '\0')
|
||||
{
|
||||
char buf[XkbKeyNameLength + 1];
|
||||
LongToKeyName(name, buf);
|
||||
memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength);
|
||||
*kc_rtrn = n;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
Bool
|
||||
FindKeyNameForAlias(XkbDescPtr xkb, unsigned long lname,
|
||||
unsigned long *real_name)
|
||||
{
|
||||
register int i;
|
||||
char name[XkbKeyNameLength + 1];
|
||||
|
||||
if (xkb && xkb->geom && xkb->geom->key_aliases)
|
||||
{
|
||||
XkbKeyAliasPtr a;
|
||||
a = xkb->geom->key_aliases;
|
||||
LongToKeyName(lname, name);
|
||||
name[XkbKeyNameLength] = '\0';
|
||||
for (i = 0; i < xkb->geom->num_key_aliases; i++, a++)
|
||||
{
|
||||
if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
|
||||
{
|
||||
*real_name = KeyNameToLong(a->real);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xkb && xkb->names && xkb->names->key_aliases)
|
||||
{
|
||||
XkbKeyAliasPtr a;
|
||||
a = xkb->names->key_aliases;
|
||||
LongToKeyName(lname, name);
|
||||
name[XkbKeyNameLength] = '\0';
|
||||
for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
|
||||
{
|
||||
if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
|
||||
{
|
||||
*real_name = KeyNameToLong(a->real);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef MISC_H
|
||||
#define MISC_H 1
|
||||
|
||||
typedef struct _CommonInfo
|
||||
{
|
||||
unsigned short defined;
|
||||
unsigned char fileID;
|
||||
unsigned char merge;
|
||||
struct _CommonInfo *next;
|
||||
} CommonInfo;
|
||||
|
||||
extern Bool UseNewField(unsigned /* field */ ,
|
||||
CommonInfo * /* oldDefs */ ,
|
||||
CommonInfo * /* newDefs */ ,
|
||||
unsigned * /* pCollide */
|
||||
);
|
||||
|
||||
extern Bool MergeNewField(unsigned /* field */ ,
|
||||
CommonInfo * /* oldDefs */ ,
|
||||
CommonInfo * /* newDefs */ ,
|
||||
unsigned * /* pCollide */
|
||||
);
|
||||
|
||||
extern XPointer ClearCommonInfo(CommonInfo * /* cmn */
|
||||
);
|
||||
|
||||
extern XPointer AddCommonInfo(CommonInfo * /* old */ ,
|
||||
CommonInfo * /* new */
|
||||
);
|
||||
|
||||
extern int ReportNotArray(const char * /* type */ ,
|
||||
const char * /* field */ ,
|
||||
const char * /* name */
|
||||
);
|
||||
|
||||
extern int ReportShouldBeArray(const char * /* type */ ,
|
||||
const char * /* field */ ,
|
||||
char * /* name */
|
||||
);
|
||||
|
||||
extern int ReportBadType(const char * /* type */ ,
|
||||
const char * /* field */ ,
|
||||
const char * /* name */ ,
|
||||
const char * /* wanted */
|
||||
);
|
||||
|
||||
extern int ReportBadIndexType(char * /* type */ ,
|
||||
char * /* field */ ,
|
||||
char * /* name */ ,
|
||||
char * /* wanted */
|
||||
);
|
||||
|
||||
extern int ReportBadField(const char * /* type */ ,
|
||||
const char * /* field */ ,
|
||||
const char * /* name */
|
||||
);
|
||||
|
||||
extern int ReportMultipleDefs(char * /* type */ ,
|
||||
char * /* field */ ,
|
||||
char * /* which */
|
||||
);
|
||||
|
||||
extern Bool ProcessIncludeFile(IncludeStmt * /* stmt */ ,
|
||||
unsigned /* file_type */ ,
|
||||
XkbFile ** /* file_rtrn */ ,
|
||||
unsigned * /* merge_rtrn */
|
||||
);
|
||||
|
||||
extern Status ComputeKbdDefaults(XkbDescPtr /* xkb */
|
||||
);
|
||||
|
||||
extern Bool FindNamedKey(XkbDescPtr /* xkb */ ,
|
||||
unsigned long /* name */ ,
|
||||
unsigned int * /* kc_rtrn */ ,
|
||||
Bool /* use_aliases */ ,
|
||||
Bool /* create */ ,
|
||||
int /* start_from */
|
||||
);
|
||||
|
||||
extern Bool FindKeyNameForAlias(XkbDescPtr /* xkb */ ,
|
||||
unsigned long /* lname */ ,
|
||||
unsigned long * /* real_name */
|
||||
);
|
||||
|
||||
#endif /* MISC_H */
|
|
@ -0,0 +1,834 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#define DEBUG_VAR parseDebug
|
||||
#include "parseutils.h"
|
||||
#include "xkbpath.h"
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
#include <X11/Xalloca.h>
|
||||
|
||||
XkbFile *rtrnValue;
|
||||
|
||||
ParseCommon *
|
||||
AppendStmt(ParseCommon * to, ParseCommon * append)
|
||||
{
|
||||
ParseCommon *start = to;
|
||||
|
||||
if (append == NULL)
|
||||
return to;
|
||||
while ((to != NULL) && (to->next != NULL))
|
||||
{
|
||||
to = to->next;
|
||||
}
|
||||
if (to)
|
||||
{
|
||||
to->next = append;
|
||||
return start;
|
||||
}
|
||||
return append;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreate(unsigned op, unsigned type)
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr = uTypedAlloc(ExprDef);
|
||||
if (expr)
|
||||
{
|
||||
expr->common.stmtType = StmtExpr;
|
||||
expr->common.next = NULL;
|
||||
expr->op = op;
|
||||
expr->type = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate expression in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateUnary(unsigned op, unsigned type, ExprDef * child)
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr = uTypedAlloc(ExprDef);
|
||||
if (expr)
|
||||
{
|
||||
expr->common.stmtType = StmtExpr;
|
||||
expr->common.next = NULL;
|
||||
expr->op = op;
|
||||
expr->type = type;
|
||||
expr->value.child = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate expression in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr = uTypedAlloc(ExprDef);
|
||||
if (expr)
|
||||
{
|
||||
expr->common.stmtType = StmtExpr;
|
||||
expr->common.next = NULL;
|
||||
expr->op = op;
|
||||
if ((op == OpAssign) || (left->type == TypeUnknown))
|
||||
expr->type = right->type;
|
||||
else if ((left->type == right->type) || (right->type == TypeUnknown))
|
||||
expr->type = left->type;
|
||||
else
|
||||
expr->type = TypeUnknown;
|
||||
expr->value.binary.left = left;
|
||||
expr->value.binary.right = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate expression in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
KeycodeDef *
|
||||
KeycodeCreate(char *name, ExprDef * value)
|
||||
{
|
||||
KeycodeDef *def;
|
||||
|
||||
def = uTypedAlloc(KeycodeDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtKeycodeDef;
|
||||
def->common.next = NULL;
|
||||
strncpy(def->name, name, XkbKeyNameLength);
|
||||
def->name[XkbKeyNameLength] = '\0';
|
||||
def->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate key name definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
KeyAliasDef *
|
||||
KeyAliasCreate(char *alias, char *real)
|
||||
{
|
||||
KeyAliasDef *def;
|
||||
|
||||
def = uTypedAlloc(KeyAliasDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtKeyAliasDef;
|
||||
def->common.next = NULL;
|
||||
strncpy(def->alias, alias, XkbKeyNameLength);
|
||||
def->alias[XkbKeyNameLength] = '\0';
|
||||
strncpy(def->real, real, XkbKeyNameLength);
|
||||
def->real[XkbKeyNameLength] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate key alias definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
VModDef *
|
||||
VModCreate(Atom name, ExprDef * value)
|
||||
{
|
||||
VModDef *def;
|
||||
def = uTypedAlloc(VModDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtVModDef;
|
||||
def->common.next = NULL;
|
||||
def->name = name;
|
||||
def->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate variable definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
VarDef *
|
||||
VarCreate(ExprDef * name, ExprDef * value)
|
||||
{
|
||||
VarDef *def;
|
||||
def = uTypedAlloc(VarDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtVarDef;
|
||||
def->common.next = NULL;
|
||||
def->name = name;
|
||||
def->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate variable definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
VarDef *
|
||||
BoolVarCreate(Atom nameToken, unsigned set)
|
||||
{
|
||||
ExprDef *name, *value;
|
||||
|
||||
name = ExprCreate(ExprIdent, TypeUnknown);
|
||||
name->value.str = nameToken;
|
||||
value = ExprCreate(ExprValue, TypeBoolean);
|
||||
value->value.uval = set;
|
||||
return VarCreate(name, value);
|
||||
}
|
||||
|
||||
InterpDef *
|
||||
InterpCreate(KeySym sym, ExprDef * match)
|
||||
{
|
||||
InterpDef *def;
|
||||
|
||||
def = uTypedAlloc(InterpDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtInterpDef;
|
||||
def->common.next = NULL;
|
||||
def->sym = sym;
|
||||
def->match = match;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate interp definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
KeyTypeDef *
|
||||
KeyTypeCreate(Atom name, VarDef * body)
|
||||
{
|
||||
KeyTypeDef *def;
|
||||
|
||||
def = uTypedAlloc(KeyTypeDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtKeyTypeDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
def->name = name;
|
||||
def->body = body;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate key type definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
SymbolsDef *
|
||||
SymbolsCreate(char *keyName, ExprDef * symbols)
|
||||
{
|
||||
SymbolsDef *def;
|
||||
|
||||
def = uTypedAlloc(SymbolsDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtSymbolsDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
bzero(def->keyName, 5);
|
||||
strncpy(def->keyName, keyName, 4);
|
||||
def->symbols = symbols;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate symbols definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
GroupCompatDef *
|
||||
GroupCompatCreate(int group, ExprDef * val)
|
||||
{
|
||||
GroupCompatDef *def;
|
||||
|
||||
def = uTypedAlloc(GroupCompatDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtGroupCompatDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
def->group = group;
|
||||
def->def = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate group compat definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
ModMapDef *
|
||||
ModMapCreate(Atom modifier, ExprDef * keys)
|
||||
{
|
||||
ModMapDef *def;
|
||||
|
||||
def = uTypedAlloc(ModMapDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtModMapDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
def->modifier = modifier;
|
||||
def->keys = keys;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate mod mask definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
IndicatorMapDef *
|
||||
IndicatorMapCreate(Atom name, VarDef * body)
|
||||
{
|
||||
IndicatorMapDef *def;
|
||||
|
||||
def = uTypedAlloc(IndicatorMapDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtIndicatorMapDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
def->name = name;
|
||||
def->body = body;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate indicator map definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
IndicatorNameDef *
|
||||
IndicatorNameCreate(int ndx, ExprDef * name, Bool virtual)
|
||||
{
|
||||
IndicatorNameDef *def;
|
||||
|
||||
def = uTypedAlloc(IndicatorNameDef);
|
||||
if (def)
|
||||
{
|
||||
def->common.stmtType = StmtIndicatorNameDef;
|
||||
def->common.next = NULL;
|
||||
def->merge = MergeDefault;
|
||||
def->ndx = ndx;
|
||||
def->name = name;
|
||||
def->virtual = virtual;
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL("Couldn't allocate indicator index definition in parser\n");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ActionCreate(Atom name, ExprDef * args)
|
||||
{
|
||||
ExprDef *act;
|
||||
|
||||
act = uTypedAlloc(ExprDef);
|
||||
if (act)
|
||||
{
|
||||
act->common.stmtType = StmtExpr;
|
||||
act->common.next = NULL;
|
||||
act->op = ExprActionDecl;
|
||||
act->value.action.name = name;
|
||||
act->value.action.args = args;
|
||||
return act;
|
||||
}
|
||||
FATAL("Couldn't allocate ActionDef in parser\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
CreateKeysymList(KeySym sym)
|
||||
{
|
||||
ExprDef *def;
|
||||
|
||||
def = ExprCreate(ExprKeysymList, TypeSymbols);
|
||||
if (def)
|
||||
{
|
||||
def->value.list.nSyms = 1;
|
||||
def->value.list.szSyms = 2;
|
||||
def->value.list.syms = uTypedCalloc(2, KeySym);
|
||||
if (def->value.list.syms != NULL)
|
||||
{
|
||||
def->value.list.syms[0] = sym;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
FATAL("Couldn't allocate expression for keysym list in parser\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ShapeDef *
|
||||
ShapeDeclCreate(Atom name, OutlineDef * outlines)
|
||||
{
|
||||
ShapeDef *shape;
|
||||
OutlineDef *ol;
|
||||
|
||||
shape = uTypedAlloc(ShapeDef);
|
||||
if (shape != NULL)
|
||||
{
|
||||
bzero(shape, sizeof(ShapeDef));
|
||||
shape->common.stmtType = StmtShapeDef;
|
||||
shape->common.next = NULL;
|
||||
shape->merge = MergeDefault;
|
||||
shape->name = name;
|
||||
shape->nOutlines = 0;
|
||||
shape->outlines = outlines;
|
||||
for (ol = outlines; ol != NULL; ol = (OutlineDef *) ol->common.next)
|
||||
{
|
||||
if (ol->nPoints > 0)
|
||||
shape->nOutlines++;
|
||||
}
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
OutlineDef *
|
||||
OutlineCreate(Atom field, ExprDef * points)
|
||||
{
|
||||
OutlineDef *outline;
|
||||
ExprDef *pt;
|
||||
|
||||
outline = uTypedAlloc(OutlineDef);
|
||||
if (outline != NULL)
|
||||
{
|
||||
bzero(outline, sizeof(OutlineDef));
|
||||
outline->common.stmtType = StmtOutlineDef;
|
||||
outline->common.next = NULL;
|
||||
outline->field = field;
|
||||
outline->nPoints = 0;
|
||||
if (points->op == ExprCoord)
|
||||
{
|
||||
for (pt = points; pt != NULL; pt = (ExprDef *) pt->common.next)
|
||||
{
|
||||
outline->nPoints++;
|
||||
}
|
||||
}
|
||||
outline->points = points;
|
||||
}
|
||||
return outline;
|
||||
}
|
||||
|
||||
KeyDef *
|
||||
KeyDeclCreate(char *name, ExprDef * expr)
|
||||
{
|
||||
KeyDef *key;
|
||||
|
||||
key = uTypedAlloc(KeyDef);
|
||||
if (key != NULL)
|
||||
{
|
||||
bzero(key, sizeof(KeyDef));
|
||||
key->common.stmtType = StmtKeyDef;
|
||||
key->common.next = NULL;
|
||||
if (name)
|
||||
key->name = name;
|
||||
else
|
||||
key->expr = expr;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
KeyDef *
|
||||
KeyDeclMerge(KeyDef * into, KeyDef * from)
|
||||
{
|
||||
into->expr =
|
||||
(ExprDef *) AppendStmt(&into->expr->common, &from->expr->common);
|
||||
from->expr = NULL;
|
||||
uFree(from);
|
||||
return into;
|
||||
}
|
||||
|
||||
RowDef *
|
||||
RowDeclCreate(KeyDef * keys)
|
||||
{
|
||||
RowDef *row;
|
||||
KeyDef *key;
|
||||
|
||||
row = uTypedAlloc(RowDef);
|
||||
if (row != NULL)
|
||||
{
|
||||
bzero(row, sizeof(RowDef));
|
||||
row->common.stmtType = StmtRowDef;
|
||||
row->common.next = NULL;
|
||||
row->nKeys = 0;
|
||||
row->keys = keys;
|
||||
for (key = keys; key != NULL; key = (KeyDef *) key->common.next)
|
||||
{
|
||||
if (key->common.stmtType == StmtKeyDef)
|
||||
row->nKeys++;
|
||||
}
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
SectionDef *
|
||||
SectionDeclCreate(Atom name, RowDef * rows)
|
||||
{
|
||||
SectionDef *section;
|
||||
RowDef *row;
|
||||
|
||||
section = uTypedAlloc(SectionDef);
|
||||
if (section != NULL)
|
||||
{
|
||||
bzero(section, sizeof(SectionDef));
|
||||
section->common.stmtType = StmtSectionDef;
|
||||
section->common.next = NULL;
|
||||
section->name = name;
|
||||
section->nRows = 0;
|
||||
section->rows = rows;
|
||||
for (row = rows; row != NULL; row = (RowDef *) row->common.next)
|
||||
{
|
||||
if (row->common.stmtType == StmtRowDef)
|
||||
section->nRows++;
|
||||
}
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
OverlayKeyDef *
|
||||
OverlayKeyCreate(char *under, char *over)
|
||||
{
|
||||
OverlayKeyDef *key;
|
||||
|
||||
key = uTypedAlloc(OverlayKeyDef);
|
||||
if (key != NULL)
|
||||
{
|
||||
bzero(key, sizeof(OverlayKeyDef));
|
||||
key->common.stmtType = StmtOverlayKeyDef;
|
||||
strncpy(key->over, over, XkbKeyNameLength);
|
||||
strncpy(key->under, under, XkbKeyNameLength);
|
||||
if (over)
|
||||
uFree(over);
|
||||
if (under)
|
||||
uFree(under);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
OverlayDef *
|
||||
OverlayDeclCreate(Atom name, OverlayKeyDef * keys)
|
||||
{
|
||||
OverlayDef *ol;
|
||||
OverlayKeyDef *key;
|
||||
|
||||
ol = uTypedAlloc(OverlayDef);
|
||||
if (ol != NULL)
|
||||
{
|
||||
bzero(ol, sizeof(OverlayDef));
|
||||
ol->common.stmtType = StmtOverlayDef;
|
||||
ol->name = name;
|
||||
ol->keys = keys;
|
||||
for (key = keys; key != NULL;
|
||||
key = (OverlayKeyDef *) key->common.next)
|
||||
{
|
||||
ol->nKeys++;
|
||||
}
|
||||
}
|
||||
return ol;
|
||||
}
|
||||
|
||||
DoodadDef *
|
||||
DoodadCreate(unsigned type, Atom name, VarDef * body)
|
||||
{
|
||||
DoodadDef *doodad;
|
||||
|
||||
doodad = uTypedAlloc(DoodadDef);
|
||||
if (doodad != NULL)
|
||||
{
|
||||
bzero(doodad, sizeof(DoodadDef));
|
||||
doodad->common.stmtType = StmtDoodadDef;
|
||||
doodad->common.next = NULL;
|
||||
doodad->type = type;
|
||||
doodad->name = name;
|
||||
doodad->body = body;
|
||||
}
|
||||
return doodad;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
AppendKeysymList(ExprDef * list, KeySym sym)
|
||||
{
|
||||
if (list->value.list.nSyms >= list->value.list.szSyms)
|
||||
{
|
||||
list->value.list.szSyms *= 2;
|
||||
list->value.list.syms = uTypedRecalloc(list->value.list.syms,
|
||||
list->value.list.nSyms,
|
||||
list->value.list.szSyms,
|
||||
KeySym);
|
||||
if (list->value.list.syms == NULL)
|
||||
{
|
||||
FATAL("Couldn't resize list of symbols for append\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
list->value.list.syms[list->value.list.nSyms++] = sym;
|
||||
return list;
|
||||
}
|
||||
|
||||
int
|
||||
LookupKeysym(char *str, KeySym * sym_rtrn)
|
||||
{
|
||||
KeySym sym;
|
||||
|
||||
if ((!str) || (uStrCaseCmp(str, "any") == 0)
|
||||
|| (uStrCaseCmp(str, "nosymbol") == 0))
|
||||
{
|
||||
*sym_rtrn = NoSymbol;
|
||||
return 1;
|
||||
}
|
||||
else if ((uStrCaseCmp(str, "none") == 0)
|
||||
|| (uStrCaseCmp(str, "voidsymbol") == 0))
|
||||
{
|
||||
*sym_rtrn = XK_VoidSymbol;
|
||||
return 1;
|
||||
}
|
||||
sym = XStringToKeysym(str);
|
||||
if (sym != NoSymbol)
|
||||
{
|
||||
*sym_rtrn = sym;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IncludeStmt *
|
||||
IncludeCreate(char *str, unsigned merge)
|
||||
{
|
||||
IncludeStmt *incl, *first;
|
||||
char *file, *map, *stmt, *tmp, *extra_data;
|
||||
char nextop;
|
||||
Bool haveSelf;
|
||||
|
||||
haveSelf = False;
|
||||
incl = first = NULL;
|
||||
file = map = NULL;
|
||||
tmp = str;
|
||||
stmt = uStringDup(str);
|
||||
while ((tmp) && (*tmp))
|
||||
{
|
||||
if (XkbParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
|
||||
{
|
||||
if ((file == NULL) && (map == NULL))
|
||||
{
|
||||
if (haveSelf)
|
||||
goto BAIL;
|
||||
haveSelf = True;
|
||||
}
|
||||
if (first == NULL)
|
||||
first = incl = uTypedAlloc(IncludeStmt);
|
||||
else
|
||||
{
|
||||
incl->next = uTypedAlloc(IncludeStmt);
|
||||
incl = incl->next;
|
||||
}
|
||||
if (incl)
|
||||
{
|
||||
incl->common.stmtType = StmtInclude;
|
||||
incl->common.next = NULL;
|
||||
incl->merge = merge;
|
||||
incl->stmt = NULL;
|
||||
incl->file = file;
|
||||
incl->map = map;
|
||||
incl->modifier = extra_data;
|
||||
incl->path = NULL;
|
||||
incl->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
WSGO("Allocation failure in IncludeCreate\n");
|
||||
ACTION("Using only part of the include\n");
|
||||
break;
|
||||
}
|
||||
if (nextop == '|')
|
||||
merge = MergeAugment;
|
||||
else
|
||||
merge = MergeOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
if (first)
|
||||
first->stmt = stmt;
|
||||
else if (stmt)
|
||||
uFree(stmt);
|
||||
return first;
|
||||
BAIL:
|
||||
ERROR1("Illegal include statement \"%s\"\n", stmt);
|
||||
ACTION("Ignored\n");
|
||||
while (first)
|
||||
{
|
||||
incl = first->next;
|
||||
if (first->file)
|
||||
uFree(first->file);
|
||||
if (first->map)
|
||||
uFree(first->map);
|
||||
if (first->modifier)
|
||||
uFree(first->modifier);
|
||||
if (first->path)
|
||||
uFree(first->path);
|
||||
first->file = first->map = first->path = NULL;
|
||||
uFree(first);
|
||||
first = incl;
|
||||
}
|
||||
if (stmt)
|
||||
uFree(stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
PrintStmtAddrs(ParseCommon * stmt)
|
||||
{
|
||||
fprintf(stderr, "0x%x", stmt);
|
||||
if (stmt)
|
||||
{
|
||||
do
|
||||
{
|
||||
fprintf(stderr, "->0x%x", stmt->next);
|
||||
stmt = stmt->next;
|
||||
}
|
||||
while (stmt);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
CheckDefaultMap(XkbFile * maps)
|
||||
{
|
||||
XkbFile *dflt, *tmp;
|
||||
|
||||
dflt = NULL;
|
||||
for (tmp = maps, dflt = NULL; tmp != NULL;
|
||||
tmp = (XkbFile *) tmp->common.next)
|
||||
{
|
||||
if (tmp->flags & XkbLC_Default)
|
||||
{
|
||||
if (dflt == NULL)
|
||||
dflt = tmp;
|
||||
else
|
||||
{
|
||||
if (warningLevel > 2)
|
||||
{
|
||||
WARN1("Multiple default components in %s\n",
|
||||
(scanFile ? scanFile : "(unknown)"));
|
||||
ACTION2("Using %s, ignoring %s\n",
|
||||
(dflt->name ? dflt->name : "(first)"),
|
||||
(tmp->name ? tmp->name : "(subsequent)"));
|
||||
}
|
||||
tmp->flags &= (~XkbLC_Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
XKBParseFile(FILE * file, XkbFile ** pRtrn)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
yyin = file;
|
||||
rtrnValue = NULL;
|
||||
if (yyparse() == 0)
|
||||
{
|
||||
*pRtrn = rtrnValue;
|
||||
CheckDefaultMap(rtrnValue);
|
||||
rtrnValue = NULL;
|
||||
return 1;
|
||||
}
|
||||
*pRtrn = NULL;
|
||||
return 0;
|
||||
}
|
||||
*pRtrn = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
|
||||
{
|
||||
XkbFile *file;
|
||||
static int fileID;
|
||||
|
||||
file = uTypedAlloc(XkbFile);
|
||||
if (file)
|
||||
{
|
||||
XkbEnsureSafeMapName(name);
|
||||
bzero(file, sizeof(XkbFile));
|
||||
file->type = type;
|
||||
file->topName = uStringDup(name);
|
||||
file->name = name;
|
||||
file->defs = defs;
|
||||
file->id = fileID++;
|
||||
file->compiled = False;
|
||||
file->flags = flags;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
unsigned
|
||||
StmtSetMerge(ParseCommon * stmt, unsigned merge)
|
||||
{
|
||||
if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
|
||||
{
|
||||
yyerror("illegal use of 'alternate' merge mode");
|
||||
merge = MergeDefault;
|
||||
}
|
||||
return merge;
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBPARSE_H
|
||||
#define XKBPARSE_H 1
|
||||
|
||||
#ifndef DEBUG_VAR
|
||||
#define DEBUG_VAR parseDebug
|
||||
#endif
|
||||
|
||||
#include "xkbcomp.h"
|
||||
|
||||
extern char *scanStr;
|
||||
extern int scanInt;
|
||||
extern int lineNum;
|
||||
|
||||
extern XkbFile *rtrnValue;
|
||||
|
||||
#ifdef DEBUG
|
||||
#define d(str) fprintf(stderr,"%s\n",str);
|
||||
#define d1(str,a) fprintf(stderr,str,a);
|
||||
#define d2(str,a,b) fprintf(stderr,str,a,b);
|
||||
#else
|
||||
#define d(str)
|
||||
#define d1(str,a)
|
||||
#define d2(str,a,b)
|
||||
#endif
|
||||
|
||||
|
||||
extern ParseCommon *AppendStmt(ParseCommon * /* to */ ,
|
||||
ParseCommon * /* append */
|
||||
);
|
||||
|
||||
extern ExprDef *ExprCreate(unsigned /* op */ ,
|
||||
unsigned /* type */
|
||||
);
|
||||
|
||||
extern ExprDef *ExprCreateUnary(unsigned /* op */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprDef * /* child */
|
||||
);
|
||||
|
||||
extern ExprDef *ExprCreateBinary(unsigned /* op */ ,
|
||||
ExprDef * /* left */ ,
|
||||
ExprDef * /* right */
|
||||
);
|
||||
|
||||
extern KeycodeDef *KeycodeCreate(char * /* name */ ,
|
||||
ExprDef * /* value */
|
||||
);
|
||||
|
||||
extern KeyAliasDef *KeyAliasCreate(char * /* alias */ ,
|
||||
char * /* real */
|
||||
);
|
||||
|
||||
extern VModDef *VModCreate(Atom /* name */ ,
|
||||
ExprDef * /* value */
|
||||
);
|
||||
|
||||
extern VarDef *VarCreate(ExprDef * /* name */ ,
|
||||
ExprDef * /* value */
|
||||
);
|
||||
|
||||
extern VarDef *BoolVarCreate(Atom /* nameToken */ ,
|
||||
unsigned /* set */
|
||||
);
|
||||
|
||||
extern InterpDef *InterpCreate(KeySym /* sym */ ,
|
||||
ExprDef * /* match */
|
||||
);
|
||||
|
||||
extern KeyTypeDef *KeyTypeCreate(Atom /* name */ ,
|
||||
VarDef * /* body */
|
||||
);
|
||||
|
||||
extern SymbolsDef *SymbolsCreate(char * /* keyName */ ,
|
||||
ExprDef * /* symbols */
|
||||
);
|
||||
|
||||
extern GroupCompatDef *GroupCompatCreate(int /* group */ ,
|
||||
ExprDef * /* def */
|
||||
);
|
||||
|
||||
extern ModMapDef *ModMapCreate(Atom /* modifier */ ,
|
||||
ExprDef * /* keys */
|
||||
);
|
||||
|
||||
extern IndicatorMapDef *IndicatorMapCreate(Atom /* name */ ,
|
||||
VarDef * /* body */
|
||||
);
|
||||
|
||||
extern IndicatorNameDef *IndicatorNameCreate(int /* ndx */ ,
|
||||
ExprDef * /* name */ ,
|
||||
Bool /* virtual */
|
||||
);
|
||||
|
||||
extern ExprDef *ActionCreate(Atom /* name */ ,
|
||||
ExprDef * /* args */
|
||||
);
|
||||
|
||||
extern ExprDef *CreateKeysymList(KeySym /* sym */
|
||||
);
|
||||
|
||||
extern ShapeDef *ShapeDeclCreate(Atom /* name */ ,
|
||||
OutlineDef * /* outlines */
|
||||
);
|
||||
|
||||
extern OutlineDef *OutlineCreate(Atom /* field */ ,
|
||||
ExprDef * /* points */
|
||||
);
|
||||
|
||||
extern KeyDef *KeyDeclCreate(char * /* name */ ,
|
||||
ExprDef * /* expr */
|
||||
);
|
||||
|
||||
extern KeyDef *KeyDeclMerge(KeyDef * /* into */ ,
|
||||
KeyDef * /* from */
|
||||
);
|
||||
|
||||
extern RowDef *RowDeclCreate(KeyDef * /* keys */
|
||||
);
|
||||
|
||||
extern SectionDef *SectionDeclCreate(Atom /* name */ ,
|
||||
RowDef * /* rows */
|
||||
);
|
||||
|
||||
extern OverlayKeyDef *OverlayKeyCreate(char * /* under */ ,
|
||||
char * /* over */
|
||||
);
|
||||
|
||||
extern OverlayDef *OverlayDeclCreate(Atom /* name */ ,
|
||||
OverlayKeyDef * /* rows */
|
||||
);
|
||||
|
||||
extern DoodadDef *DoodadCreate(unsigned /* type */ ,
|
||||
Atom /* name */ ,
|
||||
VarDef * /* body */
|
||||
);
|
||||
|
||||
extern ExprDef *AppendKeysymList(ExprDef * /* list */ ,
|
||||
KeySym /* sym */
|
||||
);
|
||||
|
||||
extern int LookupKeysym(char * /* str */ ,
|
||||
KeySym * /* sym_rtrn */
|
||||
);
|
||||
|
||||
extern IncludeStmt *IncludeCreate(char * /* str */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
extern unsigned StmtSetMerge(ParseCommon * /* stmt */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void PrintStmtAddrs(ParseCommon * /* stmt */
|
||||
);
|
||||
#endif
|
||||
|
||||
extern int XKBParseFile(FILE * /* file */ ,
|
||||
XkbFile ** /* pRtrn */
|
||||
);
|
||||
|
||||
extern XkbFile *CreateXKBFile(int /* type */ ,
|
||||
char * /* name */ ,
|
||||
ParseCommon * /* defs */ ,
|
||||
unsigned /* flags */
|
||||
);
|
||||
|
||||
extern void yyerror(const char * /* s */
|
||||
);
|
||||
|
||||
extern int yywrap(void);
|
||||
|
||||
extern int yylex(void);
|
||||
extern int yyparse(void);
|
||||
|
||||
extern int setScanState(char * /* file */ ,
|
||||
int /* line */
|
||||
);
|
||||
|
||||
extern FILE *yyin;
|
||||
|
||||
#endif /* XKBPARSE_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,104 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
#ifndef TOKENS_H
|
||||
#define TOKENS_H 1
|
||||
|
||||
#define END_OF_FILE 0
|
||||
#define ERROR_TOK 255
|
||||
|
||||
#define XKB_KEYMAP 1
|
||||
#define XKB_KEYCODES 2
|
||||
#define XKB_TYPES 3
|
||||
#define XKB_SYMBOLS 4
|
||||
#define XKB_COMPATMAP 5
|
||||
#define XKB_GEOMETRY 6
|
||||
#define XKB_SEMANTICS 7
|
||||
#define XKB_LAYOUT 8
|
||||
|
||||
#define INCLUDE 10
|
||||
#define OVERRIDE 11
|
||||
#define AUGMENT 12
|
||||
#define REPLACE 13
|
||||
#define ALTERNATE 14
|
||||
|
||||
#define VIRTUAL_MODS 20
|
||||
#define TYPE 21
|
||||
#define INTERPRET 22
|
||||
#define ACTION_TOK 23
|
||||
#define KEY 24
|
||||
#define ALIAS 25
|
||||
#define GROUP 26
|
||||
#define MODIFIER_MAP 27
|
||||
#define INDICATOR 28
|
||||
#define SHAPE 29
|
||||
#define KEYS 30
|
||||
#define ROW 31
|
||||
#define SECTION 32
|
||||
#define OVERLAY 33
|
||||
#define TEXT 34
|
||||
#define OUTLINE 35
|
||||
#define SOLID 36
|
||||
#define LOGO 37
|
||||
#define VIRTUAL 38
|
||||
|
||||
#define EQUALS 40
|
||||
#define PLUS 41
|
||||
#define MINUS 42
|
||||
#define DIVIDE 43
|
||||
#define TIMES 44
|
||||
#define OBRACE 45
|
||||
#define CBRACE 46
|
||||
#define OPAREN 47
|
||||
#define CPAREN 48
|
||||
#define OBRACKET 49
|
||||
#define CBRACKET 50
|
||||
#define DOT 51
|
||||
#define COMMA 52
|
||||
#define SEMI 53
|
||||
#define EXCLAM 54
|
||||
#define INVERT 55
|
||||
|
||||
#define STRING 60
|
||||
#define INTEGER 61
|
||||
#define FLOAT 62
|
||||
#define IDENT 63
|
||||
#define KEYNAME 64
|
||||
|
||||
#define PARTIAL 70
|
||||
#define DEFAULT 71
|
||||
#define HIDDEN 72
|
||||
#define ALPHANUMERIC_KEYS 73
|
||||
#define MODIFIER_KEYS 74
|
||||
#define KEYPAD_KEYS 75
|
||||
#define FUNCTION_KEYS 76
|
||||
#define ALTERNATE_GROUP 77
|
||||
|
||||
extern Atom tok_ONE_LEVEL;
|
||||
extern Atom tok_TWO_LEVEL;
|
||||
extern Atom tok_ALPHABETIC;
|
||||
extern Atom tok_KEYPAD;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,434 @@
|
|||
|
||||
/*\
|
||||
*
|
||||
* COPYRIGHT 1990
|
||||
* DIGITAL EQUIPMENT CORPORATION
|
||||
* MAYNARD, MASSACHUSETTS
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
|
||||
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
|
||||
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE
|
||||
* FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED
|
||||
* WARRANTY.
|
||||
*
|
||||
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
|
||||
* RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
|
||||
* ADDITION TO THAT SET FORTH ABOVE.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Digital Equipment Corporation not be
|
||||
* used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
\*/
|
||||
|
||||
#include "utils.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Opaque
|
||||
uAlloc(unsigned size)
|
||||
{
|
||||
return ((Opaque) malloc(size));
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Opaque
|
||||
uCalloc(unsigned n, unsigned size)
|
||||
{
|
||||
return ((Opaque) calloc(n, size));
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Opaque
|
||||
uRealloc(Opaque old, unsigned newSize)
|
||||
{
|
||||
if (old == NULL)
|
||||
return ((Opaque) malloc(newSize));
|
||||
else
|
||||
return ((Opaque) realloc((char *) old, newSize));
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
Opaque
|
||||
uRecalloc(Opaque old, unsigned nOld, unsigned nNew, unsigned itemSize)
|
||||
{
|
||||
char *rtrn;
|
||||
|
||||
if (old == NULL)
|
||||
rtrn = (char *) calloc(nNew, itemSize);
|
||||
else
|
||||
{
|
||||
rtrn = (char *) realloc((char *) old, nNew * itemSize);
|
||||
if ((rtrn) && (nNew > nOld))
|
||||
{
|
||||
bzero(&rtrn[nOld * itemSize], (nNew - nOld) * itemSize);
|
||||
}
|
||||
}
|
||||
return (Opaque) rtrn;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uFree(Opaque ptr)
|
||||
{
|
||||
if (ptr != (Opaque) NULL)
|
||||
free((char *) ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
/*** FUNCTION ENTRY TRACKING ***/
|
||||
/***====================================================================***/
|
||||
|
||||
static FILE *entryFile = NULL;
|
||||
int uEntryLevel;
|
||||
|
||||
Boolean
|
||||
uSetEntryFile(char *name)
|
||||
{
|
||||
if ((entryFile != NULL) && (entryFile != stderr))
|
||||
{
|
||||
fprintf(entryFile, "switching to %s\n", name ? name : "stderr");
|
||||
fclose(entryFile);
|
||||
}
|
||||
if (name != NullString)
|
||||
entryFile = fopen(name, "w");
|
||||
else
|
||||
entryFile = stderr;
|
||||
if (entryFile == NULL)
|
||||
{
|
||||
entryFile = stderr;
|
||||
return (False);
|
||||
}
|
||||
return (True);
|
||||
}
|
||||
|
||||
void
|
||||
uEntry(int l, char *s, ...)
|
||||
{
|
||||
int i;
|
||||
va_list args;
|
||||
|
||||
for (i = 0; i < uEntryLevel; i++)
|
||||
{
|
||||
putc(' ', entryFile);
|
||||
}
|
||||
va_start(args, s);
|
||||
vfprintf(entryFile, s, args);
|
||||
va_end(args);
|
||||
uEntryLevel += l;
|
||||
}
|
||||
|
||||
void
|
||||
uExit(int l, char *rtVal)
|
||||
{
|
||||
int i;
|
||||
|
||||
uEntryLevel -= l;
|
||||
if (uEntryLevel < 0)
|
||||
uEntryLevel = 0;
|
||||
for (i = 0; i < uEntryLevel; i++)
|
||||
{
|
||||
putc(' ', entryFile);
|
||||
}
|
||||
fprintf(entryFile, "---> %p\n", rtVal);
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
/*** PRINT FUNCTIONS ***/
|
||||
/***====================================================================***/
|
||||
|
||||
FILE *uDebugFile = NULL;
|
||||
int uDebugIndentLevel = 0;
|
||||
int uDebugIndentSize = 4;
|
||||
|
||||
Boolean
|
||||
uSetDebugFile(char *name)
|
||||
{
|
||||
if ((uDebugFile != NULL) && (uDebugFile != stderr))
|
||||
{
|
||||
fprintf(uDebugFile, "switching to %s\n", name ? name : "stderr");
|
||||
fclose(uDebugFile);
|
||||
}
|
||||
if (name != NullString)
|
||||
uDebugFile = fopen(name, "w");
|
||||
else
|
||||
uDebugFile = stderr;
|
||||
if (uDebugFile == NULL)
|
||||
{
|
||||
uDebugFile = stderr;
|
||||
return (False);
|
||||
}
|
||||
return (True);
|
||||
}
|
||||
|
||||
void
|
||||
uDebug(char *s, ...)
|
||||
{
|
||||
int i;
|
||||
va_list args;
|
||||
|
||||
for (i = (uDebugIndentLevel * uDebugIndentSize); i > 0; i--)
|
||||
{
|
||||
putc(' ', uDebugFile);
|
||||
}
|
||||
va_start(args, s);
|
||||
vfprintf(uDebugFile, s, args);
|
||||
va_end(args);
|
||||
fflush(uDebugFile);
|
||||
}
|
||||
|
||||
void
|
||||
uDebugNOI(char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, s);
|
||||
vfprintf(uDebugFile, s, args);
|
||||
va_end(args);
|
||||
fflush(uDebugFile);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static FILE *errorFile = NULL;
|
||||
static int outCount = 0;
|
||||
static char *preMsg = NULL;
|
||||
static char *postMsg = NULL;
|
||||
static char *prefix = NULL;
|
||||
|
||||
Boolean
|
||||
uSetErrorFile(char *name)
|
||||
{
|
||||
if ((errorFile != NULL) && (errorFile != stderr))
|
||||
{
|
||||
fprintf(errorFile, "switching to %s\n", name ? name : "stderr");
|
||||
fclose(errorFile);
|
||||
}
|
||||
if (name != NullString)
|
||||
errorFile = fopen(name, "w");
|
||||
else
|
||||
errorFile = stderr;
|
||||
if (errorFile == NULL)
|
||||
{
|
||||
errorFile = stderr;
|
||||
return (False);
|
||||
}
|
||||
return (True);
|
||||
}
|
||||
|
||||
void
|
||||
uInformation(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fflush(errorFile);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uAction(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (prefix != NULL)
|
||||
fprintf(errorFile, "%s", prefix);
|
||||
fprintf(errorFile, " ");
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fflush(errorFile);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uWarning(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if ((outCount == 0) && (preMsg != NULL))
|
||||
fprintf(errorFile, "%s\n", preMsg);
|
||||
if (prefix != NULL)
|
||||
fprintf(errorFile, "%s", prefix);
|
||||
fprintf(errorFile, "Warning: ");
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fflush(errorFile);
|
||||
outCount++;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uError(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if ((outCount == 0) && (preMsg != NULL))
|
||||
fprintf(errorFile, "%s\n", preMsg);
|
||||
if (prefix != NULL)
|
||||
fprintf(errorFile, "%s", prefix);
|
||||
fprintf(errorFile, "Error: ");
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fflush(errorFile);
|
||||
outCount++;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uFatalError(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if ((outCount == 0) && (preMsg != NULL))
|
||||
fprintf(errorFile, "%s\n", preMsg);
|
||||
if (prefix != NULL)
|
||||
fprintf(errorFile, "%s", prefix);
|
||||
fprintf(errorFile, "Fatal Error: ");
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fprintf(errorFile, " Exiting\n");
|
||||
fflush(errorFile);
|
||||
outCount++;
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
void
|
||||
uInternalError(const char *s, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if ((outCount == 0) && (preMsg != NULL))
|
||||
fprintf(errorFile, "%s\n", preMsg);
|
||||
if (prefix != NULL)
|
||||
fprintf(errorFile, "%s", prefix);
|
||||
fprintf(errorFile, "Internal error: ");
|
||||
va_start(args, s);
|
||||
vfprintf(errorFile, s, args);
|
||||
va_end(args);
|
||||
fflush(errorFile);
|
||||
outCount++;
|
||||
}
|
||||
|
||||
void
|
||||
uSetPreErrorMessage(char *msg)
|
||||
{
|
||||
outCount = 0;
|
||||
preMsg = msg;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
uSetPostErrorMessage(char *msg)
|
||||
{
|
||||
postMsg = msg;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
uSetErrorPrefix(char *pre)
|
||||
{
|
||||
prefix = pre;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
uFinishUp(void)
|
||||
{
|
||||
if ((outCount > 0) && (postMsg != NULL))
|
||||
fprintf(errorFile, "%s\n", postMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *
|
||||
uStringDup(const char *str)
|
||||
{
|
||||
char *rtrn;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
rtrn = (char *) uAlloc(strlen(str) + 1);
|
||||
strcpy(rtrn, str);
|
||||
return rtrn;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
int
|
||||
uStrCaseCmp(const char *str1, const char *str2)
|
||||
{
|
||||
char buf1[512], buf2[512];
|
||||
char c, *s;
|
||||
register int n;
|
||||
|
||||
for (n = 0, s = buf1; (c = *str1++); n++)
|
||||
{
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
if (n > 510)
|
||||
break;
|
||||
*s++ = c;
|
||||
}
|
||||
*s = '\0';
|
||||
for (n = 0, s = buf2; (c = *str2++); n++)
|
||||
{
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
if (n > 510)
|
||||
break;
|
||||
*s++ = c;
|
||||
}
|
||||
*s = '\0';
|
||||
return (strcmp(buf1, buf2));
|
||||
}
|
||||
|
||||
int
|
||||
uStrCasePrefix(const char *my_prefix, char *str)
|
||||
{
|
||||
char c1;
|
||||
char c2;
|
||||
while (((c1 = *my_prefix) != '\0') && ((c2 = *str) != '\0'))
|
||||
{
|
||||
if (isupper(c1))
|
||||
c1 = tolower(c1);
|
||||
if (isupper(c2))
|
||||
c2 = tolower(c2);
|
||||
if (c1 != c2)
|
||||
return 0;
|
||||
my_prefix++;
|
||||
str++;
|
||||
}
|
||||
if (c1 != '\0')
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,381 @@
|
|||
#ifndef UTILS_H
|
||||
#define UTILS_H 1
|
||||
|
||||
/*\
|
||||
*
|
||||
* COPYRIGHT 1990
|
||||
* DIGITAL EQUIPMENT CORPORATION
|
||||
* MAYNARD, MASSACHUSETTS
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
|
||||
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
|
||||
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE
|
||||
* FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED
|
||||
* WARRANTY.
|
||||
*
|
||||
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
|
||||
* RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
|
||||
* ADDITION TO THAT SET FORTH ABOVE.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Digital Equipment Corporation not be
|
||||
* used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
\*/
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xfuncproto.h>
|
||||
#include <X11/Xfuncs.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifndef NUL
|
||||
#define NUL '\0'
|
||||
#endif
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#ifndef OPAQUE_DEFINED
|
||||
typedef void *Opaque;
|
||||
#endif
|
||||
#ifndef NullOpaque
|
||||
#define NullOpaque ((Opaque)NULL)
|
||||
#endif
|
||||
|
||||
#ifndef BOOLEAN_DEFINED
|
||||
typedef char Boolean;
|
||||
#endif
|
||||
|
||||
#ifndef True
|
||||
#define True ((Boolean)1)
|
||||
#define False ((Boolean)0)
|
||||
#endif /* ndef True */
|
||||
#define booleanText(b) ((b)?"True":"False")
|
||||
|
||||
#ifndef COMPARISON_DEFINED
|
||||
typedef int Comparison;
|
||||
|
||||
#define Greater ((Comparison)1)
|
||||
#define Equal ((Comparison)0)
|
||||
#define Less ((Comparison)-1)
|
||||
#define CannotCompare ((Comparison)-37)
|
||||
#define comparisonText(c) ((c)?((c)<0?"Less":"Greater"):"Equal")
|
||||
#endif
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
extern Opaque uAlloc(unsigned /* size */
|
||||
);
|
||||
extern Opaque uCalloc(unsigned /* n */ ,
|
||||
unsigned /* size */
|
||||
);
|
||||
extern Opaque uRealloc(Opaque /* old */ ,
|
||||
unsigned /* newSize */
|
||||
);
|
||||
extern Opaque uRecalloc(Opaque /* old */ ,
|
||||
unsigned /* nOld */ ,
|
||||
unsigned /* nNew */ ,
|
||||
unsigned /* newSize */
|
||||
);
|
||||
extern void uFree(Opaque /* ptr */
|
||||
);
|
||||
|
||||
#define uTypedAlloc(t) ((t *)uAlloc((unsigned)sizeof(t)))
|
||||
#define uTypedCalloc(n,t) ((t *)uCalloc((unsigned)n,(unsigned)sizeof(t)))
|
||||
#define uTypedRealloc(pO,n,t) ((t *)uRealloc((Opaque)pO,((unsigned)n)*sizeof(t)))
|
||||
#define uTypedRecalloc(pO,o,n,t) ((t *)uRecalloc((Opaque)pO,((unsigned)o),((unsigned)n),sizeof(t)))
|
||||
#if (defined mdHasAlloca) && (mdHasAlloca)
|
||||
#define uTmpAlloc(n) ((Opaque)alloca((unsigned)n))
|
||||
#define uTmpFree(p)
|
||||
#else
|
||||
#define uTmpAlloc(n) uAlloc(n)
|
||||
#define uTmpFree(p) uFree(p)
|
||||
#endif
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
extern Boolean uSetErrorFile(char * /* name */
|
||||
);
|
||||
|
||||
#define INFO6 uInformation
|
||||
#define INFO5 uInformation
|
||||
#define INFO4 uInformation
|
||||
#define INFO3 uInformation
|
||||
#define INFO2 uInformation
|
||||
#define INFO1 uInformation
|
||||
#define INFO uInformation
|
||||
|
||||
extern void
|
||||
uInformation(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#define ACTION6 uAction
|
||||
#define ACTION5 uAction
|
||||
#define ACTION4 uAction
|
||||
#define ACTION3 uAction
|
||||
#define ACTION2 uAction
|
||||
#define ACTION1 uAction
|
||||
#define ACTION uAction
|
||||
|
||||
extern void uAction(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#define WARN6 uWarning
|
||||
#define WARN5 uWarning
|
||||
#define WARN4 uWarning
|
||||
#define WARN3 uWarning
|
||||
#define WARN2 uWarning
|
||||
#define WARN1 uWarning
|
||||
#define WARN uWarning
|
||||
|
||||
extern void uWarning(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#define ERROR6 uError
|
||||
#define ERROR5 uError
|
||||
#define ERROR4 uError
|
||||
#define ERROR3 uError
|
||||
#define ERROR2 uError
|
||||
#define ERROR1 uError
|
||||
#define ERROR uError
|
||||
|
||||
extern void uError(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#define FATAL6 uFatalError
|
||||
#define FATAL5 uFatalError
|
||||
#define FATAL4 uFatalError
|
||||
#define FATAL3 uFatalError
|
||||
#define FATAL2 uFatalError
|
||||
#define FATAL1 uFatalError
|
||||
#define FATAL uFatalError
|
||||
|
||||
extern void uFatalError(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* WSGO stands for "Weird Stuff Going On" */
|
||||
#define WSGO6 uInternalError
|
||||
#define WSGO5 uInternalError
|
||||
#define WSGO4 uInternalError
|
||||
#define WSGO3 uInternalError
|
||||
#define WSGO2 uInternalError
|
||||
#define WSGO1 uInternalError
|
||||
#define WSGO uInternalError
|
||||
|
||||
extern void uInternalError(const char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
extern void uSetPreErrorMessage(char * /* msg */
|
||||
);
|
||||
|
||||
extern void uSetPostErrorMessage(char * /* msg */
|
||||
);
|
||||
|
||||
extern void uSetErrorPrefix(char * /* void */
|
||||
);
|
||||
|
||||
extern void uFinishUp(void);
|
||||
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#define NullString ((char *)NULL)
|
||||
|
||||
#define uStringText(s) ((s)==NullString?"<NullString>":(s))
|
||||
#define uStringEqual(s1,s2) (uStringCompare(s1,s2)==Equal)
|
||||
#define uStringPrefix(p,s) (strncmp(p,s,strlen(p))==0)
|
||||
#define uStringCompare(s1,s2) (((s1)==NullString||(s2)==NullString)?\
|
||||
(s1)!=(s2):strcmp(s1,s2))
|
||||
#define uStrCaseEqual(s1,s2) (uStrCaseCmp(s1,s2)==0)
|
||||
#ifdef HAVE_STRCASECMP
|
||||
#define uStrCaseCmp(s1,s2) (strcasecmp(s1,s2))
|
||||
#define uStrCasePrefix(p,s) (strncasecmp(p,s,strlen(p))==0)
|
||||
#else
|
||||
extern int uStrCaseCmp(const char * /* s1 */ ,
|
||||
const char * /* s2 */
|
||||
);
|
||||
extern int uStrCasePrefix(const char * /* p */ ,
|
||||
char * /* str */
|
||||
);
|
||||
#endif
|
||||
#ifdef HAVE_STRDUP
|
||||
#define uStringDup(s1) ((s1) ? strdup(s1) : NULL)
|
||||
#else
|
||||
extern char *uStringDup(const char * /* s1 */
|
||||
);
|
||||
#endif
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#ifdef ASSERTIONS_ON
|
||||
#define uASSERT(where,why) \
|
||||
{if (!(why)) uFatalError("assertion botched in %s ( why )\n",where);}
|
||||
#else
|
||||
#define uASSERT(where,why)
|
||||
#endif
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
#ifndef DEBUG_VAR
|
||||
#define DEBUG_VAR debugFlags
|
||||
#endif
|
||||
|
||||
extern
|
||||
unsigned int DEBUG_VAR;
|
||||
|
||||
extern void uDebug(char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
extern void uDebugNOI( /* no indent */
|
||||
char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
extern Boolean uSetDebugFile(char *name);
|
||||
|
||||
extern FILE *uDebugFile;
|
||||
extern int uDebugIndentLevel;
|
||||
extern int uDebugIndentSize;
|
||||
#define uDebugIndent(l) (uDebugIndentLevel+=(l))
|
||||
#define uDebugOutdent(l) (uDebugIndentLevel-=(l))
|
||||
#ifdef DEBUG_ON
|
||||
#define uDEBUG(f,s) { if (DEBUG_VAR&(f)) uDebug(s);}
|
||||
#define uDEBUG1(f,s,a) { if (DEBUG_VAR&(f)) uDebug(s,a);}
|
||||
#define uDEBUG2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebug(s,a,b);}
|
||||
#define uDEBUG3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c);}
|
||||
#define uDEBUG4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d);}
|
||||
#define uDEBUG5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d,e);}
|
||||
#define uDEBUG_NOI(f,s) { if (DEBUG_VAR&(f)) uDebug(s);}
|
||||
#define uDEBUG_NOI1(f,s,a) { if (DEBUG_VAR&(f)) uDebugNOI(s,a);}
|
||||
#define uDEBUG_NOI2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b);}
|
||||
#define uDEBUG_NOI3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c);}
|
||||
#define uDEBUG_NOI4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d);}
|
||||
#define uDEBUG_NOI5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d,e);}
|
||||
#else
|
||||
#define uDEBUG(f,s)
|
||||
#define uDEBUG1(f,s,a)
|
||||
#define uDEBUG2(f,s,a,b)
|
||||
#define uDEBUG3(f,s,a,b,c)
|
||||
#define uDEBUG4(f,s,a,b,c,d)
|
||||
#define uDEBUG5(f,s,a,b,c,d,e)
|
||||
#define uDEBUG_NOI(f,s)
|
||||
#define uDEBUG_NOI1(f,s,a)
|
||||
#define uDEBUG_NOI2(f,s,a,b)
|
||||
#define uDEBUG_NOI3(f,s,a,b,c)
|
||||
#define uDEBUG_NOI4(f,s,a,b,c,d)
|
||||
#define uDEBUG_NOI5(f,s,a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
extern Boolean uSetEntryFile(char *name);
|
||||
extern void uEntry(int /* l */ ,
|
||||
char * /* s */ , ...
|
||||
)
|
||||
#if defined(__GNUC__) && \
|
||||
((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6)))
|
||||
__attribute__ ((format(printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
|
||||
extern void uExit(int l, char *rtVal);
|
||||
#ifdef ENTRY_TRACKING_ON
|
||||
#define ENTRY_BIT 0x10
|
||||
#define LOW_ENTRY_BIT 0x1000
|
||||
#define ENTER (DEBUG_VAR&ENTRY_BIT)
|
||||
#define FLAG(fLag) (DEBUG_VAR&(fLag))
|
||||
|
||||
extern int uEntryLevel;
|
||||
|
||||
#define uENTRY(s) { if (ENTER) uEntry(1,s);}
|
||||
#define uENTRY1(s,a) { if (ENTER) uEntry(1,s,a);}
|
||||
#define uENTRY2(s,a,b) { if (ENTER) uEntry(1,s,a,b);}
|
||||
#define uENTRY3(s,a,b,c) { if (ENTER) uEntry(1,s,a,b,c);}
|
||||
#define uENTRY4(s,a,b,c,d) { if (ENTER) uEntry(1,s,a,b,c,d);}
|
||||
#define uENTRY5(s,a,b,c,d,e) { if (ENTER) uEntry(1,s,a,b,c,d,e);}
|
||||
#define uENTRY6(s,a,b,c,d,e,f) { if (ENTER) uEntry(1,s,a,b,c,d,e,f);}
|
||||
#define uENTRY7(s,a,b,c,d,e,f,g) { if (ENTER) uEntry(1,s,a,b,c,d,e,f,g);}
|
||||
#define uRETURN(v) { if (ENTER) uEntryLevel--; return(v); }
|
||||
#define uVOIDRETURN { if (ENTER) uEntryLevel--; return; }
|
||||
|
||||
#define uFLAG_ENTRY(w,s) { if (FLAG(w)) uEntry(0,s);}
|
||||
#define uFLAG_ENTRY1(w,s,a) { if (FLAG(w)) uEntry(0,s,a);}
|
||||
#define uFLAG_ENTRY2(w,s,a,b) { if (FLAG(w)) uEntry(0,s,a,b);}
|
||||
#define uFLAG_ENTRY3(w,s,a,b,c) { if (FLAG(w)) uEntry(0,s,a,b,c);}
|
||||
#define uFLAG_ENTRY4(w,s,a,b,c,d) { if (FLAG(w)) uEntry(0,s,a,b,c,d);}
|
||||
#define uFLAG_ENTRY5(w,s,a,b,c,d,e) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e);}
|
||||
#define uFLAG_ENTRY6(w,s,a,b,c,d,e,f) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e,f);}
|
||||
#define uFLAG_ENTRY7(w,s,a,b,c,d,e,f,g) { if(FLAG(w))uEntry(0,s,a,b,c,d,e,f,g);}
|
||||
#define uFLAG_RETURN(v) { return(v);}
|
||||
#define uFLAG_VOIDRETURN { return; }
|
||||
#else
|
||||
#define uENTRY(s)
|
||||
#define uENTRY1(s,a)
|
||||
#define uENTRY2(s,a1,a2)
|
||||
#define uENTRY3(s,a1,a2,a3)
|
||||
#define uENTRY4(s,a1,a2,a3,a4)
|
||||
#define uENTRY5(s,a1,a2,a3,a4,a5)
|
||||
#define uENTRY6(s,a1,a2,a3,a4,a5,a6)
|
||||
#define uENTRY7(s,a1,a2,a3,a4,a5,a6,a7)
|
||||
#define uRETURN(v) { return(v); }
|
||||
#define uVOIDRETURN { return; }
|
||||
|
||||
#define uFLAG_ENTRY(f,s)
|
||||
#define uFLAG_ENTRY1(f,s,a)
|
||||
#define uFLAG_ENTRY2(f,s,a,b)
|
||||
#define uFLAG_ENTRY3(f,s,a,b,c)
|
||||
#define uFLAG_ENTRY4(f,s,a,b,c,d)
|
||||
#define uFLAG_ENTRY5(f,s,a,b,c,d,e)
|
||||
#define uFLAG_ENTRY6(f,s,a,b,c,d,e,g)
|
||||
#define uFLAG_ENTRY7(f,s,a,b,c,d,e,g,h)
|
||||
#define uFLAG_RETURN(v) { return(v);}
|
||||
#define uFLAG_VOIDRETURN { return; }
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* UTILS_H */
|
|
@ -0,0 +1,271 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#define DEBUG_VAR debugFlags
|
||||
#include <stdio.h>
|
||||
#include "xkbcomp.h"
|
||||
#include "tokens.h"
|
||||
#include "expr.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include <X11/extensions/XKB.h>
|
||||
#include <X11/extensions/XKBstr.h>
|
||||
|
||||
#include "vmod.h"
|
||||
|
||||
void
|
||||
InitVModInfo(VModInfo * info, XkbDescPtr xkb)
|
||||
{
|
||||
ClearVModInfo(info, xkb);
|
||||
info->errorCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ClearVModInfo(VModInfo * info, XkbDescPtr xkb)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (XkbAllocNames(xkb, XkbVirtualModNamesMask, 0, 0) != Success)
|
||||
return;
|
||||
if (XkbAllocServerMap(xkb, XkbVirtualModsMask, 0) != Success)
|
||||
return;
|
||||
info->xkb = xkb;
|
||||
info->newlyDefined = info->defined = info->available = 0;
|
||||
if (xkb && xkb->names)
|
||||
{
|
||||
register int bit;
|
||||
for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1)
|
||||
{
|
||||
if (xkb->names->vmods[i] != None)
|
||||
info->defined |= bit;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
/**
|
||||
* Handle one entry in the virtualModifiers line (e.g. NumLock).
|
||||
* If the entry is e.g. NumLock=Mod1, stmt->value is not NULL, and the
|
||||
* XkbServerMap's vmod is set to the given modifier. Otherwise, the vmod is 0.
|
||||
*
|
||||
* @param stmt The statement specifying the name and (if any the value).
|
||||
* @param mergeMode Merge strategy (e.g. MergeOverride)
|
||||
*/
|
||||
Bool
|
||||
HandleVModDef(VModDef * stmt, unsigned mergeMode, VModInfo * info)
|
||||
{
|
||||
register int i, bit, nextFree;
|
||||
ExprResult mod;
|
||||
XkbServerMapPtr srv;
|
||||
XkbNamesPtr names;
|
||||
Atom stmtName;
|
||||
|
||||
srv = info->xkb->server;
|
||||
names = info->xkb->names;
|
||||
stmtName =
|
||||
XkbInternAtom(info->xkb->dpy, XkbAtomGetString(NULL, stmt->name),
|
||||
False);
|
||||
for (i = 0, bit = 1, nextFree = -1; i < XkbNumVirtualMods; i++, bit <<= 1)
|
||||
{
|
||||
if (info->defined & bit)
|
||||
{
|
||||
if (names->vmods[i] == stmtName)
|
||||
{ /* already defined */
|
||||
info->available |= bit;
|
||||
if (stmt->value == NULL)
|
||||
return True;
|
||||
else
|
||||
{
|
||||
char *str1;
|
||||
const char *str2 = "";
|
||||
if (!ExprResolveModMask(stmt->value, &mod, NULL, NULL))
|
||||
{
|
||||
str1 = XkbAtomText(NULL, stmt->name, XkbMessage);
|
||||
ACTION1("Declaration of %s ignored\n", str1);
|
||||
return False;
|
||||
}
|
||||
if (mod.uval == srv->vmods[i])
|
||||
return True;
|
||||
|
||||
str1 = XkbAtomText(NULL, stmt->name, XkbMessage);
|
||||
WARN1("Virtual modifier %s multiply defined\n", str1);
|
||||
str1 = XkbModMaskText(srv->vmods[i], XkbCFile);
|
||||
if (mergeMode == MergeOverride)
|
||||
{
|
||||
str2 = str1;
|
||||
str1 = XkbModMaskText(mod.uval, XkbCFile);
|
||||
}
|
||||
ACTION2("Using %s, ignoring %s\n", str1, str2);
|
||||
if (mergeMode == MergeOverride)
|
||||
srv->vmods[i] = mod.uval;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nextFree < 0)
|
||||
nextFree = i;
|
||||
}
|
||||
if (nextFree < 0)
|
||||
{
|
||||
ERROR1("Too many virtual modifiers defined (maximum %d)\n",
|
||||
XkbNumVirtualMods);
|
||||
ACTION("Exiting\n");
|
||||
return False;
|
||||
}
|
||||
info->defined |= (1 << nextFree);
|
||||
info->newlyDefined |= (1 << nextFree);
|
||||
info->available |= (1 << nextFree);
|
||||
names->vmods[nextFree] = stmtName;
|
||||
if (stmt->value == NULL)
|
||||
return True;
|
||||
if (ExprResolveModMask(stmt->value, &mod, NULL, NULL))
|
||||
{
|
||||
srv->vmods[nextFree] = mod.uval;
|
||||
return True;
|
||||
}
|
||||
ACTION1("Declaration of %s ignored\n",
|
||||
XkbAtomText(NULL, stmt->name, XkbMessage));
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the given modifier in the xkb->names->vmods array.
|
||||
*
|
||||
* @param priv Pointer to the xkb data structure.
|
||||
* @param elem Must be None, otherwise return False.
|
||||
* @param field The Atom of the modifier's name (e.g. Atom for LAlt)
|
||||
* @param type Must be TypeInt, otherwise return False.
|
||||
* @param val_rtrn Set to the index of the modifier that matches.
|
||||
*
|
||||
* @return True on success, False otherwise. If False is returned, val_rtrn is
|
||||
* undefined.
|
||||
*/
|
||||
int
|
||||
LookupVModIndex(XPointer priv,
|
||||
Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
|
||||
{
|
||||
register int i;
|
||||
register char *fieldStr;
|
||||
register char *modStr;
|
||||
XkbDescPtr xkb;
|
||||
|
||||
xkb = (XkbDescPtr) priv;
|
||||
if ((xkb == NULL) || (xkb->names == NULL) || (elem != None)
|
||||
|| (type != TypeInt))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
/* get the actual name */
|
||||
fieldStr = XkbAtomGetString(xkb->dpy, field);
|
||||
if (fieldStr == NULL)
|
||||
return False;
|
||||
/* For each named modifier, get the name and compare it to the one passed
|
||||
* in. If we get a match, return the index of the modifier.
|
||||
* The order of modifiers is the same as in the virtual_modifiers line in
|
||||
* the xkb_types section.
|
||||
*/
|
||||
for (i = 0; i < XkbNumVirtualMods; i++)
|
||||
{
|
||||
modStr = XkbAtomGetString(xkb->dpy, xkb->names->vmods[i]);
|
||||
if ((modStr != NULL) && (uStrCaseCmp(fieldStr, modStr) == 0))
|
||||
{
|
||||
val_rtrn->uval = i;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mask for the given modifier and set val_rtrn.uval to the mask.
|
||||
* Note that the mask returned is always > 512.
|
||||
*
|
||||
* @param priv Pointer to xkb data structure.
|
||||
* @param val_rtrn Set to the mask returned.
|
||||
*
|
||||
* @return True on success, False otherwise. If False is returned, val_rtrn is
|
||||
* undefined.
|
||||
*/
|
||||
int
|
||||
LookupVModMask(XPointer priv,
|
||||
Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
|
||||
{
|
||||
if (LookupVModIndex(priv, elem, field, type, val_rtrn))
|
||||
{
|
||||
register unsigned ndx = val_rtrn->uval;
|
||||
val_rtrn->uval = (1 << (XkbNumModifiers + ndx));
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
int
|
||||
FindKeypadVMod(XkbDescPtr xkb)
|
||||
{
|
||||
Atom name;
|
||||
ExprResult rtrn;
|
||||
|
||||
name = XkbInternAtom(xkb->dpy, "NumLock", False);
|
||||
if ((xkb) && LookupVModIndex((XPointer) xkb, None, name, TypeInt, &rtrn))
|
||||
{
|
||||
return rtrn.ival;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bool
|
||||
ResolveVirtualModifier(ExprDef * def, ExprResult * val_rtrn, VModInfo * info)
|
||||
{
|
||||
XkbNamesPtr names;
|
||||
|
||||
names = info->xkb->names;
|
||||
if (def->op == ExprIdent)
|
||||
{
|
||||
register int i, bit;
|
||||
for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1)
|
||||
{
|
||||
char *str1, *str2;
|
||||
str1 = XkbAtomGetString(info->xkb->dpy, names->vmods[i]);
|
||||
str2 = XkbAtomGetString(NULL, def->value.str);
|
||||
if ((info->available & bit) && (uStrCaseCmp(str1, str2) == Equal))
|
||||
{
|
||||
val_rtrn->uval = i;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ExprResolveInteger(def, val_rtrn, NULL, NULL))
|
||||
{
|
||||
if (val_rtrn->uval < XkbNumVirtualMods)
|
||||
return True;
|
||||
ERROR2("Illegal virtual modifier %d (must be 0..%d inclusive)\n",
|
||||
val_rtrn->uval, XkbNumVirtualMods - 1);
|
||||
}
|
||||
return False;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef VMOD_H
|
||||
#define VMOD_H 1
|
||||
|
||||
typedef struct _VModInfo
|
||||
{
|
||||
XkbDescPtr xkb;
|
||||
unsigned defined;
|
||||
unsigned available;
|
||||
unsigned newlyDefined;
|
||||
int errorCount;
|
||||
} VModInfo;
|
||||
|
||||
extern void InitVModInfo(VModInfo * /* info */ ,
|
||||
XkbDescPtr /* xkb */
|
||||
);
|
||||
|
||||
extern void ClearVModInfo(VModInfo * /* info */ ,
|
||||
XkbDescPtr /* xkb */
|
||||
);
|
||||
|
||||
extern Bool HandleVModDef(VModDef * /* stmt */ ,
|
||||
unsigned /* mergeMode */ ,
|
||||
VModInfo * /* info */
|
||||
);
|
||||
|
||||
extern Bool ApplyVModDefs(VModInfo * /* info */ ,
|
||||
XkbDescPtr /* xkb */
|
||||
);
|
||||
|
||||
extern int LookupVModIndex(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int LookupVModMask(XPointer /* priv */ ,
|
||||
Atom /* elem */ ,
|
||||
Atom /* field */ ,
|
||||
unsigned /* type */ ,
|
||||
ExprResult * /* val_rtrn */
|
||||
);
|
||||
|
||||
extern int FindKeypadVMod(XkbDescPtr /* xkb */
|
||||
);
|
||||
|
||||
extern Bool ResolveVirtualModifier(ExprDef * /* def */ ,
|
||||
ExprResult * /* value_rtrn */ ,
|
||||
VModInfo * /* info */
|
||||
);
|
||||
|
||||
#endif /* VMOD_H */
|
|
@ -0,0 +1,396 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_H
|
||||
#define XKBCOMP_H 1
|
||||
|
||||
#ifndef DEBUG_VAR
|
||||
#define DEBUG_VAR debugFlags
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <X11/extensions/XKM.h>
|
||||
#include <X11/extensions/XKBfile.h>
|
||||
|
||||
extern char *scanFile;
|
||||
|
||||
#define TypeUnknown 0
|
||||
#define TypeBoolean 1
|
||||
#define TypeInt 2
|
||||
#define TypeFloat 3
|
||||
#define TypeString 4
|
||||
#define TypeAction 5
|
||||
#define TypeKeyName 6
|
||||
#define TypeSymbols 7
|
||||
|
||||
#define StmtUnknown 0
|
||||
#define StmtInclude 1
|
||||
#define StmtKeycodeDef 2
|
||||
#define StmtKeyAliasDef 3
|
||||
#define StmtExpr 4
|
||||
#define StmtVarDef 5
|
||||
#define StmtKeyTypeDef 6
|
||||
#define StmtInterpDef 7
|
||||
#define StmtVModDef 8
|
||||
#define StmtSymbolsDef 9
|
||||
#define StmtModMapDef 10
|
||||
#define StmtGroupCompatDef 11
|
||||
#define StmtIndicatorMapDef 12
|
||||
#define StmtIndicatorNameDef 13
|
||||
#define StmtOutlineDef 14
|
||||
#define StmtShapeDef 15
|
||||
#define StmtKeyDef 16
|
||||
#define StmtRowDef 17
|
||||
#define StmtSectionDef 18
|
||||
#define StmtOverlayKeyDef 19
|
||||
#define StmtOverlayDef 20
|
||||
#define StmtDoodadDef 21
|
||||
|
||||
#define FileSymInterp 100
|
||||
|
||||
typedef struct _ParseCommon
|
||||
{
|
||||
unsigned stmtType;
|
||||
struct _ParseCommon *next;
|
||||
} ParseCommon;
|
||||
|
||||
#define ExprValue 0
|
||||
#define ExprIdent 1
|
||||
#define ExprActionDecl 2
|
||||
#define ExprFieldRef 3
|
||||
#define ExprArrayRef 4
|
||||
#define ExprKeysymList 5
|
||||
#define ExprActionList 6
|
||||
#define ExprCoord 7
|
||||
|
||||
#define OpAdd 20
|
||||
#define OpSubtract 21
|
||||
#define OpMultiply 22
|
||||
#define OpDivide 23
|
||||
#define OpAssign 24
|
||||
#define OpNot 25
|
||||
#define OpNegate 26
|
||||
#define OpInvert 27
|
||||
#define OpUnaryPlus 28
|
||||
|
||||
#define MergeDefault 0
|
||||
#define MergeAugment 1
|
||||
#define MergeOverride 2
|
||||
#define MergeReplace 3
|
||||
#define MergeAltForm 4
|
||||
|
||||
#define AutoKeyNames (1L << 0)
|
||||
#define CreateKeyNames(x) ((x)->flags&AutoKeyNames)
|
||||
|
||||
extern unsigned warningLevel;
|
||||
extern unsigned optionalParts;
|
||||
|
||||
typedef struct _IncludeStmt
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
char *stmt;
|
||||
char *file;
|
||||
char *map;
|
||||
char *modifier;
|
||||
char *path;
|
||||
struct _IncludeStmt *next;
|
||||
} IncludeStmt;
|
||||
|
||||
typedef struct _Expr
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned op;
|
||||
unsigned type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct _Expr *left;
|
||||
struct _Expr *right;
|
||||
} binary;
|
||||
struct
|
||||
{
|
||||
Atom element;
|
||||
Atom field;
|
||||
} field;
|
||||
struct
|
||||
{
|
||||
Atom element;
|
||||
Atom field;
|
||||
struct _Expr *entry;
|
||||
} array;
|
||||
struct
|
||||
{
|
||||
Atom name;
|
||||
struct _Expr *args;
|
||||
} action;
|
||||
struct
|
||||
{
|
||||
int nSyms;
|
||||
int szSyms;
|
||||
KeySym *syms;
|
||||
} list;
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} coord;
|
||||
struct _Expr *child;
|
||||
Atom str;
|
||||
unsigned uval;
|
||||
int ival;
|
||||
char keyName[5];
|
||||
Opaque ptr;
|
||||
} value;
|
||||
} ExprDef;
|
||||
|
||||
typedef struct _VarDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
ExprDef *name;
|
||||
ExprDef *value;
|
||||
} VarDef;
|
||||
|
||||
typedef struct _VModDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom name;
|
||||
ExprDef *value;
|
||||
} VModDef;
|
||||
|
||||
typedef struct _KeycodeDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
char name[5];
|
||||
ExprDef *value;
|
||||
} KeycodeDef;
|
||||
|
||||
typedef struct _KeyAliasDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
char alias[5];
|
||||
char real[5];
|
||||
} KeyAliasDef;
|
||||
|
||||
typedef struct _KeyTypeDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom name;
|
||||
VarDef *body;
|
||||
} KeyTypeDef;
|
||||
|
||||
typedef struct _SymbolsDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
char keyName[5];
|
||||
ExprDef *symbols;
|
||||
} SymbolsDef;
|
||||
|
||||
typedef struct _ModMapDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom modifier;
|
||||
ExprDef *keys;
|
||||
} ModMapDef;
|
||||
|
||||
typedef struct _GroupCompatDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
int group;
|
||||
ExprDef *def;
|
||||
} GroupCompatDef;
|
||||
|
||||
typedef struct _InterpDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
KeySym sym;
|
||||
ExprDef *match;
|
||||
VarDef *def;
|
||||
} InterpDef;
|
||||
|
||||
typedef struct _IndicatorNameDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
int ndx;
|
||||
ExprDef *name;
|
||||
Bool virtual;
|
||||
} IndicatorNameDef;
|
||||
|
||||
typedef struct _OutlineDef
|
||||
{
|
||||
ParseCommon common;
|
||||
Atom field;
|
||||
int nPoints;
|
||||
ExprDef *points;
|
||||
} OutlineDef;
|
||||
|
||||
typedef struct _ShapeDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom name;
|
||||
int nOutlines;
|
||||
OutlineDef *outlines;
|
||||
} ShapeDef;
|
||||
|
||||
typedef struct _KeyDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned defined;
|
||||
char *name;
|
||||
ExprDef *expr;
|
||||
} KeyDef;
|
||||
|
||||
typedef struct _RowDef
|
||||
{
|
||||
ParseCommon common;
|
||||
int nKeys;
|
||||
KeyDef *keys;
|
||||
} RowDef;
|
||||
|
||||
typedef struct _SectionDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom name;
|
||||
int nRows;
|
||||
RowDef *rows;
|
||||
} SectionDef;
|
||||
|
||||
typedef struct _OverlayKeyDef
|
||||
{
|
||||
ParseCommon common;
|
||||
char over[5];
|
||||
char under[5];
|
||||
} OverlayKeyDef;
|
||||
|
||||
typedef struct _OverlayDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
Atom name;
|
||||
int nKeys;
|
||||
OverlayKeyDef *keys;
|
||||
} OverlayDef;
|
||||
|
||||
typedef struct _DoodadDef
|
||||
{
|
||||
ParseCommon common;
|
||||
unsigned merge;
|
||||
unsigned type;
|
||||
Atom name;
|
||||
VarDef *body;
|
||||
} DoodadDef;
|
||||
|
||||
/* IndicatorMapDef doesn't use the type field, but the rest of the fields
|
||||
need to be at the same offsets as in DoodadDef. Use #define to avoid
|
||||
any strict aliasing problems. */
|
||||
#define IndicatorMapDef DoodadDef
|
||||
|
||||
typedef struct _XkbFile
|
||||
{
|
||||
ParseCommon common;
|
||||
int type;
|
||||
char *topName;
|
||||
char *name;
|
||||
ParseCommon *defs;
|
||||
int id;
|
||||
unsigned flags;
|
||||
Bool compiled;
|
||||
} XkbFile;
|
||||
|
||||
extern Bool CompileKeymap(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
extern Bool CompileKeycodes(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
extern Bool CompileGeometry(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
extern Bool CompileKeyTypes(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
typedef struct _LEDInfo *LEDInfoPtr;
|
||||
|
||||
extern Bool CompileCompatMap(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */ ,
|
||||
LEDInfoPtr * /* unboundLEDs */
|
||||
);
|
||||
|
||||
extern Bool CompileSymbols(XkbFile * /* file */ ,
|
||||
XkbFileInfo * /* result */ ,
|
||||
unsigned /* merge */
|
||||
);
|
||||
|
||||
#define WantLongListing (1<<0)
|
||||
#define WantPartialMaps (1<<1)
|
||||
#define WantHiddenMaps (1<<2)
|
||||
#define WantFullNames (1<<3)
|
||||
#define ListRecursive (1<<4)
|
||||
|
||||
extern char *rootDir;
|
||||
extern unsigned verboseLevel;
|
||||
extern unsigned dirsToStrip;
|
||||
|
||||
extern Bool AddListing(char * /* file */ ,
|
||||
char * /* map */
|
||||
);
|
||||
|
||||
extern Bool AddMatchingFiles(char * /* head_in */
|
||||
);
|
||||
|
||||
extern int AddMapOnly(char * /* map */
|
||||
);
|
||||
|
||||
extern int GenerateListing(char * /* filename */
|
||||
);
|
||||
|
||||
#endif /* XKBCOMP_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,799 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
%token
|
||||
END_OF_FILE 0
|
||||
ERROR_TOK 255
|
||||
XKB_KEYMAP 1
|
||||
XKB_KEYCODES 2
|
||||
XKB_TYPES 3
|
||||
XKB_SYMBOLS 4
|
||||
XKB_COMPATMAP 5
|
||||
XKB_GEOMETRY 6
|
||||
XKB_SEMANTICS 7
|
||||
XKB_LAYOUT 8
|
||||
INCLUDE 10
|
||||
OVERRIDE 11
|
||||
AUGMENT 12
|
||||
REPLACE 13
|
||||
ALTERNATE 14
|
||||
VIRTUAL_MODS 20
|
||||
TYPE 21
|
||||
INTERPRET 22
|
||||
ACTION_TOK 23
|
||||
KEY 24
|
||||
ALIAS 25
|
||||
GROUP 26
|
||||
MODIFIER_MAP 27
|
||||
INDICATOR 28
|
||||
SHAPE 29
|
||||
KEYS 30
|
||||
ROW 31
|
||||
SECTION 32
|
||||
OVERLAY 33
|
||||
TEXT 34
|
||||
OUTLINE 35
|
||||
SOLID 36
|
||||
LOGO 37
|
||||
VIRTUAL 38
|
||||
EQUALS 40
|
||||
PLUS 41
|
||||
MINUS 42
|
||||
DIVIDE 43
|
||||
TIMES 44
|
||||
OBRACE 45
|
||||
CBRACE 46
|
||||
OPAREN 47
|
||||
CPAREN 48
|
||||
OBRACKET 49
|
||||
CBRACKET 50
|
||||
DOT 51
|
||||
COMMA 52
|
||||
SEMI 53
|
||||
EXCLAM 54
|
||||
INVERT 55
|
||||
STRING 60
|
||||
INTEGER 61
|
||||
FLOAT 62
|
||||
IDENT 63
|
||||
KEYNAME 64
|
||||
PARTIAL 70
|
||||
DEFAULT 71
|
||||
HIDDEN 72
|
||||
ALPHANUMERIC_KEYS 73
|
||||
MODIFIER_KEYS 74
|
||||
KEYPAD_KEYS 75
|
||||
FUNCTION_KEYS 76
|
||||
ALTERNATE_GROUP 77
|
||||
%{
|
||||
#ifdef DEBUG
|
||||
#define YYDEBUG 1
|
||||
#endif
|
||||
#define DEBUG_VAR parseDebug
|
||||
#include "parseutils.h"
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned int parseDebug;
|
||||
|
||||
%}
|
||||
%right EQUALS
|
||||
%left PLUS MINUS
|
||||
%left TIMES DIVIDE
|
||||
%left EXCLAM INVERT
|
||||
%left OPAREN
|
||||
%start XkbFile
|
||||
%union {
|
||||
int ival;
|
||||
unsigned uval;
|
||||
char *str;
|
||||
Atom sval;
|
||||
ParseCommon *any;
|
||||
ExprDef *expr;
|
||||
VarDef *var;
|
||||
VModDef *vmod;
|
||||
InterpDef *interp;
|
||||
KeyTypeDef *keyType;
|
||||
SymbolsDef *syms;
|
||||
ModMapDef *modMask;
|
||||
GroupCompatDef *groupCompat;
|
||||
IndicatorMapDef *ledMap;
|
||||
IndicatorNameDef *ledName;
|
||||
KeycodeDef *keyName;
|
||||
KeyAliasDef *keyAlias;
|
||||
ShapeDef *shape;
|
||||
SectionDef *section;
|
||||
RowDef *row;
|
||||
KeyDef *key;
|
||||
OverlayDef *overlay;
|
||||
OverlayKeyDef *olKey;
|
||||
OutlineDef *outline;
|
||||
DoodadDef *doodad;
|
||||
XkbFile *file;
|
||||
}
|
||||
%type <ival> Number Integer Float SignedNumber
|
||||
%type <uval> XkbCompositeType FileType MergeMode OptMergeMode KeySym
|
||||
%type <uval> DoodadType Flag Flags OptFlags
|
||||
%type <str> KeyName MapName OptMapName
|
||||
%type <sval> FieldSpec Ident Element String
|
||||
%type <any> DeclList Decl
|
||||
%type <expr> OptExprList ExprList Expr Term Lhs Terminal ArrayInit
|
||||
%type <expr> OptKeySymList KeySymList Action ActionList Coord CoordList
|
||||
%type <var> VarDecl VarDeclList SymbolsBody SymbolsVarDecl
|
||||
%type <vmod> VModDecl VModDefList VModDef
|
||||
%type <interp> InterpretDecl InterpretMatch
|
||||
%type <keyType> KeyTypeDecl
|
||||
%type <syms> SymbolsDecl
|
||||
%type <modMask> ModMapDecl
|
||||
%type <groupCompat> GroupCompatDecl
|
||||
%type <ledMap> IndicatorMapDecl
|
||||
%type <ledName> IndicatorNameDecl
|
||||
%type <keyName> KeyNameDecl
|
||||
%type <keyAlias> KeyAliasDecl
|
||||
%type <shape> ShapeDecl
|
||||
%type <section> SectionDecl
|
||||
%type <row> SectionBody SectionBodyItem
|
||||
%type <key> RowBody RowBodyItem Keys Key
|
||||
%type <overlay> OverlayDecl
|
||||
%type <olKey> OverlayKeyList OverlayKey
|
||||
%type <outline> OutlineList OutlineInList
|
||||
%type <doodad> DoodadDecl
|
||||
%type <file> XkbFile XkbMapConfigList XkbMapConfig XkbConfig
|
||||
%type <file> XkbCompositeMap XkbCompMapList
|
||||
%%
|
||||
XkbFile : XkbCompMapList
|
||||
{ $$= rtrnValue= $1; }
|
||||
| XkbMapConfigList
|
||||
{ $$= rtrnValue= $1; }
|
||||
| XkbConfig
|
||||
{ $$= rtrnValue= $1; }
|
||||
;
|
||||
|
||||
XkbCompMapList : XkbCompMapList XkbCompositeMap
|
||||
{ $$= (XkbFile *)AppendStmt(&$1->common,&$2->common); }
|
||||
| XkbCompositeMap
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
XkbCompositeMap : OptFlags XkbCompositeType OptMapName OBRACE
|
||||
XkbMapConfigList
|
||||
CBRACE SEMI
|
||||
{ $$= CreateXKBFile($2,$3,&$5->common,$1); }
|
||||
;
|
||||
|
||||
XkbCompositeType: XKB_KEYMAP { $$= XkmKeymapFile; }
|
||||
| XKB_SEMANTICS { $$= XkmSemanticsFile; }
|
||||
| XKB_LAYOUT { $$= XkmLayoutFile; }
|
||||
;
|
||||
|
||||
XkbMapConfigList : XkbMapConfigList XkbMapConfig
|
||||
{ $$= (XkbFile *)AppendStmt(&$1->common,&$2->common); }
|
||||
| XkbMapConfig
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
XkbMapConfig : OptFlags FileType OptMapName OBRACE
|
||||
DeclList
|
||||
CBRACE SEMI
|
||||
{ $$= CreateXKBFile($2,$3,$5,$1); }
|
||||
;
|
||||
|
||||
XkbConfig : OptFlags FileType OptMapName DeclList
|
||||
{ $$= CreateXKBFile($2,$3,$4,$1); }
|
||||
;
|
||||
|
||||
|
||||
FileType : XKB_KEYCODES { $$= XkmKeyNamesIndex; }
|
||||
| XKB_TYPES { $$= XkmTypesIndex; }
|
||||
| XKB_COMPATMAP { $$= XkmCompatMapIndex; }
|
||||
| XKB_SYMBOLS { $$= XkmSymbolsIndex; }
|
||||
| XKB_GEOMETRY { $$= XkmGeometryIndex; }
|
||||
;
|
||||
|
||||
OptFlags : Flags { $$= $1; }
|
||||
| { $$= 0; }
|
||||
;
|
||||
|
||||
Flags : Flags Flag { $$= (($1)|($2)); }
|
||||
| Flag { $$= $1; }
|
||||
;
|
||||
|
||||
Flag : PARTIAL { $$= XkbLC_Partial; }
|
||||
| DEFAULT { $$= XkbLC_Default; }
|
||||
| HIDDEN { $$= XkbLC_Hidden; }
|
||||
| ALPHANUMERIC_KEYS { $$= XkbLC_AlphanumericKeys; }
|
||||
| MODIFIER_KEYS { $$= XkbLC_ModifierKeys; }
|
||||
| KEYPAD_KEYS { $$= XkbLC_KeypadKeys; }
|
||||
| FUNCTION_KEYS { $$= XkbLC_FunctionKeys; }
|
||||
| ALTERNATE_GROUP { $$= XkbLC_AlternateGroup; }
|
||||
;
|
||||
|
||||
DeclList : DeclList Decl
|
||||
{ $$= AppendStmt($1,$2); }
|
||||
| { $$= NULL; }
|
||||
;
|
||||
|
||||
Decl : OptMergeMode VarDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode VModDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode InterpretDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode KeyNameDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode KeyAliasDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode KeyTypeDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode SymbolsDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode ModMapDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode GroupCompatDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode IndicatorMapDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode IndicatorNameDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode ShapeDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode SectionDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| OptMergeMode DoodadDecl
|
||||
{
|
||||
$2->merge= StmtSetMerge(&$2->common,$1);
|
||||
$$= &$2->common;
|
||||
}
|
||||
| MergeMode STRING
|
||||
{
|
||||
if ($1==MergeAltForm) {
|
||||
yyerror("cannot use 'alternate' to include other maps");
|
||||
$$= &IncludeCreate(scanStr,MergeDefault)->common;
|
||||
}
|
||||
else {
|
||||
$$= &IncludeCreate(scanStr,$1)->common;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
VarDecl : Lhs EQUALS Expr SEMI
|
||||
{ $$= VarCreate($1,$3); }
|
||||
| Ident SEMI
|
||||
{ $$= BoolVarCreate($1,1); }
|
||||
| EXCLAM Ident SEMI
|
||||
{ $$= BoolVarCreate($2,0); }
|
||||
;
|
||||
|
||||
KeyNameDecl : KeyName EQUALS Expr SEMI
|
||||
{
|
||||
KeycodeDef *def;
|
||||
|
||||
def= KeycodeCreate($1,$3);
|
||||
if ($1)
|
||||
free($1);
|
||||
$$= def;
|
||||
}
|
||||
;
|
||||
|
||||
KeyAliasDecl : ALIAS KeyName EQUALS KeyName SEMI
|
||||
{
|
||||
KeyAliasDef *def;
|
||||
def= KeyAliasCreate($2,$4);
|
||||
if ($2) free($2);
|
||||
if ($4) free($4);
|
||||
$$= def;
|
||||
}
|
||||
;
|
||||
|
||||
VModDecl : VIRTUAL_MODS VModDefList SEMI
|
||||
{ $$= $2; }
|
||||
;
|
||||
|
||||
VModDefList : VModDefList COMMA VModDef
|
||||
{ $$= (VModDef *)AppendStmt(&$1->common,&$3->common); }
|
||||
| VModDef
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
VModDef : Ident
|
||||
{ $$= VModCreate($1,NULL); }
|
||||
| Ident EQUALS Expr
|
||||
{ $$= VModCreate($1,$3); }
|
||||
;
|
||||
|
||||
InterpretDecl : INTERPRET InterpretMatch OBRACE
|
||||
VarDeclList
|
||||
CBRACE SEMI
|
||||
{
|
||||
$2->def= $4;
|
||||
$$= $2;
|
||||
}
|
||||
;
|
||||
|
||||
InterpretMatch : KeySym PLUS Expr
|
||||
{ $$= InterpCreate((KeySym)$1,$3); }
|
||||
| KeySym
|
||||
{ $$= InterpCreate((KeySym)$1,NULL); }
|
||||
;
|
||||
|
||||
VarDeclList : VarDeclList VarDecl
|
||||
{ $$= (VarDef *)AppendStmt(&$1->common,&$2->common); }
|
||||
| VarDecl
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
KeyTypeDecl : TYPE String OBRACE
|
||||
VarDeclList
|
||||
CBRACE SEMI
|
||||
{ $$= KeyTypeCreate($2,$4); }
|
||||
;
|
||||
|
||||
SymbolsDecl : KEY KeyName OBRACE
|
||||
SymbolsBody
|
||||
CBRACE SEMI
|
||||
{ $$= SymbolsCreate($2,(ExprDef *)$4); }
|
||||
;
|
||||
|
||||
SymbolsBody : SymbolsBody COMMA SymbolsVarDecl
|
||||
{ $$= (VarDef *)AppendStmt(&$1->common,&$3->common); }
|
||||
| SymbolsVarDecl
|
||||
{ $$= $1; }
|
||||
| { $$= NULL; }
|
||||
;
|
||||
|
||||
SymbolsVarDecl : Lhs EQUALS Expr
|
||||
{ $$= VarCreate($1,$3); }
|
||||
| Lhs EQUALS ArrayInit
|
||||
{ $$= VarCreate($1,$3); }
|
||||
| Ident
|
||||
{ $$= BoolVarCreate($1,1); }
|
||||
| EXCLAM Ident
|
||||
{ $$= BoolVarCreate($2,0); }
|
||||
| ArrayInit
|
||||
{ $$= VarCreate(NULL,$1); }
|
||||
;
|
||||
|
||||
ArrayInit : OBRACKET OptKeySymList CBRACKET
|
||||
{ $$= $2; }
|
||||
| OBRACKET ActionList CBRACKET
|
||||
{ $$= ExprCreateUnary(ExprActionList,TypeAction,$2); }
|
||||
;
|
||||
|
||||
GroupCompatDecl : GROUP Integer EQUALS Expr SEMI
|
||||
{ $$= GroupCompatCreate($2,$4); }
|
||||
;
|
||||
|
||||
ModMapDecl : MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI
|
||||
{ $$= ModMapCreate($2,$4); }
|
||||
;
|
||||
|
||||
IndicatorMapDecl: INDICATOR String OBRACE VarDeclList CBRACE SEMI
|
||||
{ $$= IndicatorMapCreate($2,$4); }
|
||||
;
|
||||
|
||||
IndicatorNameDecl: INDICATOR Integer EQUALS Expr SEMI
|
||||
{ $$= IndicatorNameCreate($2,$4,False); }
|
||||
| VIRTUAL INDICATOR Integer EQUALS Expr SEMI
|
||||
{ $$= IndicatorNameCreate($3,$5,True); }
|
||||
;
|
||||
|
||||
ShapeDecl : SHAPE String OBRACE OutlineList CBRACE SEMI
|
||||
{ $$= ShapeDeclCreate($2,(OutlineDef *)&$4->common); }
|
||||
| SHAPE String OBRACE CoordList CBRACE SEMI
|
||||
{
|
||||
OutlineDef *outlines;
|
||||
outlines= OutlineCreate(None,$4);
|
||||
$$= ShapeDeclCreate($2,outlines);
|
||||
}
|
||||
;
|
||||
|
||||
SectionDecl : SECTION String OBRACE SectionBody CBRACE SEMI
|
||||
{ $$= SectionDeclCreate($2,$4); }
|
||||
;
|
||||
|
||||
SectionBody : SectionBody SectionBodyItem
|
||||
{ $$=(RowDef *)AppendStmt(&$1->common,&$2->common);}
|
||||
| SectionBodyItem
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
SectionBodyItem : ROW OBRACE RowBody CBRACE SEMI
|
||||
{ $$= RowDeclCreate($3); }
|
||||
| VarDecl
|
||||
{ $$= (RowDef *)$1; }
|
||||
| DoodadDecl
|
||||
{ $$= (RowDef *)$1; }
|
||||
| IndicatorMapDecl
|
||||
{ $$= (RowDef *)$1; }
|
||||
| OverlayDecl
|
||||
{ $$= (RowDef *)$1; }
|
||||
;
|
||||
|
||||
RowBody : RowBody RowBodyItem
|
||||
{ $$=(KeyDef *)AppendStmt(&$1->common,&$2->common);}
|
||||
| RowBodyItem
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
RowBodyItem : KEYS OBRACE Keys CBRACE SEMI
|
||||
{ $$= $3; }
|
||||
| VarDecl
|
||||
{ $$= (KeyDef *)$1; }
|
||||
;
|
||||
|
||||
Keys : Keys COMMA Key
|
||||
{ $$=(KeyDef *)AppendStmt(&$1->common,&$3->common);}
|
||||
| Key
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
Key : KeyName
|
||||
{ $$= KeyDeclCreate($1,NULL); }
|
||||
| OBRACE ExprList CBRACE
|
||||
{ $$= KeyDeclCreate(NULL,$2); }
|
||||
;
|
||||
|
||||
OverlayDecl : OVERLAY String OBRACE OverlayKeyList CBRACE SEMI
|
||||
{ $$= OverlayDeclCreate($2,$4); }
|
||||
;
|
||||
|
||||
OverlayKeyList : OverlayKeyList COMMA OverlayKey
|
||||
{
|
||||
$$= (OverlayKeyDef *)
|
||||
AppendStmt(&$1->common,&$3->common);
|
||||
}
|
||||
| OverlayKey
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
OverlayKey : KeyName EQUALS KeyName
|
||||
{ $$= OverlayKeyCreate($1,$3); }
|
||||
;
|
||||
|
||||
OutlineList : OutlineList COMMA OutlineInList
|
||||
{ $$=(OutlineDef *)AppendStmt(&$1->common,&$3->common);}
|
||||
| OutlineInList
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
OutlineInList : OBRACE CoordList CBRACE
|
||||
{ $$= OutlineCreate(None,$2); }
|
||||
| Ident EQUALS OBRACE CoordList CBRACE
|
||||
{ $$= OutlineCreate($1,$4); }
|
||||
| Ident EQUALS Expr
|
||||
{ $$= OutlineCreate($1,$3); }
|
||||
;
|
||||
|
||||
CoordList : CoordList COMMA Coord
|
||||
{ $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); }
|
||||
| Coord
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
Coord : OBRACKET SignedNumber COMMA SignedNumber CBRACKET
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprCoord,TypeUnknown);
|
||||
expr->value.coord.x= $2;
|
||||
expr->value.coord.y= $4;
|
||||
$$= expr;
|
||||
}
|
||||
;
|
||||
|
||||
DoodadDecl : DoodadType String OBRACE VarDeclList CBRACE SEMI
|
||||
{ $$= DoodadCreate($1,$2,$4); }
|
||||
;
|
||||
|
||||
DoodadType : TEXT { $$= XkbTextDoodad; }
|
||||
| OUTLINE { $$= XkbOutlineDoodad; }
|
||||
| SOLID { $$= XkbSolidDoodad; }
|
||||
| LOGO { $$= XkbLogoDoodad; }
|
||||
;
|
||||
|
||||
FieldSpec : Ident { $$= $1; }
|
||||
| Element { $$= $1; }
|
||||
;
|
||||
|
||||
Element : ACTION_TOK
|
||||
{ $$= XkbInternAtom(NULL,"action",False); }
|
||||
| INTERPRET
|
||||
{ $$= XkbInternAtom(NULL,"interpret",False); }
|
||||
| TYPE
|
||||
{ $$= XkbInternAtom(NULL,"type",False); }
|
||||
| KEY
|
||||
{ $$= XkbInternAtom(NULL,"key",False); }
|
||||
| GROUP
|
||||
{ $$= XkbInternAtom(NULL,"group",False); }
|
||||
| MODIFIER_MAP
|
||||
{$$=XkbInternAtom(NULL,"modifier_map",False);}
|
||||
| INDICATOR
|
||||
{ $$= XkbInternAtom(NULL,"indicator",False); }
|
||||
| SHAPE
|
||||
{ $$= XkbInternAtom(NULL,"shape",False); }
|
||||
| ROW
|
||||
{ $$= XkbInternAtom(NULL,"row",False); }
|
||||
| SECTION
|
||||
{ $$= XkbInternAtom(NULL,"section",False); }
|
||||
| TEXT
|
||||
{ $$= XkbInternAtom(NULL,"text",False); }
|
||||
;
|
||||
|
||||
OptMergeMode : MergeMode { $$= $1; }
|
||||
| { $$= MergeDefault; }
|
||||
;
|
||||
|
||||
MergeMode : INCLUDE { $$= MergeDefault; }
|
||||
| AUGMENT { $$= MergeAugment; }
|
||||
| OVERRIDE { $$= MergeOverride; }
|
||||
| REPLACE { $$= MergeReplace; }
|
||||
| ALTERNATE { $$= MergeAltForm; }
|
||||
;
|
||||
|
||||
OptExprList : ExprList { $$= $1; }
|
||||
| { $$= NULL; }
|
||||
;
|
||||
|
||||
ExprList : ExprList COMMA Expr
|
||||
{ $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); }
|
||||
| Expr
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
Expr : Expr DIVIDE Expr
|
||||
{ $$= ExprCreateBinary(OpDivide,$1,$3); }
|
||||
| Expr PLUS Expr
|
||||
{ $$= ExprCreateBinary(OpAdd,$1,$3); }
|
||||
| Expr MINUS Expr
|
||||
{ $$= ExprCreateBinary(OpSubtract,$1,$3); }
|
||||
| Expr TIMES Expr
|
||||
{ $$= ExprCreateBinary(OpMultiply,$1,$3); }
|
||||
| Lhs EQUALS Expr
|
||||
{ $$= ExprCreateBinary(OpAssign,$1,$3); }
|
||||
| Term
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
Term : MINUS Term
|
||||
{ $$= ExprCreateUnary(OpNegate,$2->type,$2); }
|
||||
| PLUS Term
|
||||
{ $$= ExprCreateUnary(OpUnaryPlus,$2->type,$2); }
|
||||
| EXCLAM Term
|
||||
{ $$= ExprCreateUnary(OpNot,TypeBoolean,$2); }
|
||||
| INVERT Term
|
||||
{ $$= ExprCreateUnary(OpInvert,$2->type,$2); }
|
||||
| Lhs
|
||||
{ $$= $1; }
|
||||
| FieldSpec OPAREN OptExprList CPAREN %prec OPAREN
|
||||
{ $$= ActionCreate($1,$3); }
|
||||
| Terminal
|
||||
{ $$= $1; }
|
||||
| OPAREN Expr CPAREN
|
||||
{ $$= $2; }
|
||||
;
|
||||
|
||||
ActionList : ActionList COMMA Action
|
||||
{ $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); }
|
||||
| Action
|
||||
{ $$= $1; }
|
||||
;
|
||||
|
||||
Action : FieldSpec OPAREN OptExprList CPAREN
|
||||
{ $$= ActionCreate($1,$3); }
|
||||
;
|
||||
|
||||
Lhs : FieldSpec
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprIdent,TypeUnknown);
|
||||
expr->value.str= $1;
|
||||
$$= expr;
|
||||
}
|
||||
| FieldSpec DOT FieldSpec
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprFieldRef,TypeUnknown);
|
||||
expr->value.field.element= $1;
|
||||
expr->value.field.field= $3;
|
||||
$$= expr;
|
||||
}
|
||||
| FieldSpec OBRACKET Expr CBRACKET
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprArrayRef,TypeUnknown);
|
||||
expr->value.array.element= None;
|
||||
expr->value.array.field= $1;
|
||||
expr->value.array.entry= $3;
|
||||
$$= expr;
|
||||
}
|
||||
| FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprArrayRef,TypeUnknown);
|
||||
expr->value.array.element= $1;
|
||||
expr->value.array.field= $3;
|
||||
expr->value.array.entry= $5;
|
||||
$$= expr;
|
||||
}
|
||||
;
|
||||
|
||||
Terminal : String
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprValue,TypeString);
|
||||
expr->value.str= $1;
|
||||
$$= expr;
|
||||
}
|
||||
| Integer
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprValue,TypeInt);
|
||||
expr->value.ival= $1;
|
||||
$$= expr;
|
||||
}
|
||||
| Float
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprValue,TypeFloat);
|
||||
expr->value.ival= $1;
|
||||
$$= expr;
|
||||
}
|
||||
| KeyName
|
||||
{
|
||||
ExprDef *expr;
|
||||
expr= ExprCreate(ExprValue,TypeKeyName);
|
||||
memset(expr->value.keyName,0,5);
|
||||
strncpy(expr->value.keyName,$1,4);
|
||||
free($1);
|
||||
$$= expr;
|
||||
}
|
||||
;
|
||||
|
||||
OptKeySymList : KeySymList { $$= $1; }
|
||||
| { $$= NULL; }
|
||||
;
|
||||
|
||||
KeySymList : KeySymList COMMA KeySym
|
||||
{ $$= AppendKeysymList($1,(KeySym)$3); }
|
||||
| KeySym
|
||||
{ $$= CreateKeysymList((KeySym)$1); }
|
||||
;
|
||||
|
||||
KeySym : IDENT
|
||||
{
|
||||
KeySym sym;
|
||||
if (LookupKeysym(scanStr,&sym))
|
||||
$$= sym;
|
||||
else {
|
||||
char buf[120];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"expected keysym, got %s",
|
||||
uStringText(scanStr));
|
||||
yyerror(buf);
|
||||
yynerrs++;
|
||||
$$= NoSymbol;
|
||||
}
|
||||
}
|
||||
| SECTION
|
||||
{
|
||||
$$= XK_section;
|
||||
}
|
||||
| Integer
|
||||
{
|
||||
if ($1<10) $$= $1+'0'; /* XK_0 .. XK_9 */
|
||||
else $$= $1;
|
||||
}
|
||||
;
|
||||
|
||||
SignedNumber : MINUS Number { $$= -$2; }
|
||||
| Number { $$= $1; }
|
||||
;
|
||||
|
||||
Number : FLOAT { $$= scanInt; }
|
||||
| INTEGER { $$= scanInt*XkbGeomPtsPerMM; }
|
||||
;
|
||||
|
||||
Float : FLOAT { $$= scanInt; }
|
||||
;
|
||||
|
||||
Integer : INTEGER { $$= scanInt; }
|
||||
;
|
||||
|
||||
KeyName : KEYNAME { $$= scanStr; scanStr= NULL; }
|
||||
;
|
||||
|
||||
Ident : IDENT { $$= XkbInternAtom(NULL,scanStr,False); }
|
||||
| DEFAULT { $$= XkbInternAtom(NULL,"default",False); }
|
||||
;
|
||||
|
||||
String : STRING { $$= XkbInternAtom(NULL,scanStr,False); }
|
||||
;
|
||||
|
||||
OptMapName : MapName { $$= $1; }
|
||||
| { $$= NULL; }
|
||||
;
|
||||
|
||||
MapName : STRING { $$= scanStr; scanStr= NULL; }
|
||||
;
|
||||
%%
|
||||
void
|
||||
yyerror(const char *s)
|
||||
{
|
||||
if (warningLevel>0) {
|
||||
(void)fprintf(stderr,"%s: line %d of %s\n",s,lineNum,
|
||||
(scanFile?scanFile:"(unknown)"));
|
||||
if ((scanStr)&&(warningLevel>3))
|
||||
(void)fprintf(stderr,"last scanned symbol is: %s\n",scanStr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,420 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#define DEBUG_VAR debugFlags
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <X11/extensions/XKM.h>
|
||||
#include "xkbpath.h"
|
||||
|
||||
#ifndef DFLT_XKB_CONFIG_ROOT
|
||||
#define DFLT_XKB_CONFIG_ROOT "/usr/lib/X11/xkb"
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
#define PATH_CHUNK 8 /* initial szPath */
|
||||
|
||||
static Bool noDefaultPath = False;
|
||||
static int szPath; /* number of entries allocated for includePath */
|
||||
static int nPathEntries; /* number of actual entries in includePath */
|
||||
static char **includePath; /* Holds all directories we might be including data from */
|
||||
|
||||
/**
|
||||
* Extract the first token from an include statement.
|
||||
* @param str_inout Input statement, modified in-place. Can be passed in
|
||||
* repeatedly. If str_inout is NULL, the parsing has completed.
|
||||
* @param file_rtrn Set to the include file to be used.
|
||||
* @param map_rtrn Set to whatever comes after ), if any.
|
||||
* @param nextop_rtrn Set to the next operation in the complete statement.
|
||||
* @param extra_data Set to the string between ( and ), if any.
|
||||
*
|
||||
* @return True if parsing was succcessful, False for an illegal string.
|
||||
*
|
||||
* Example: "evdev+aliases(qwerty)"
|
||||
* str_inout = aliases(qwerty)
|
||||
* nextop_retrn = +
|
||||
* extra_data = NULL
|
||||
* file_rtrn = evdev
|
||||
* map_rtrn = NULL
|
||||
*
|
||||
* 2nd run with "aliases(qwerty)"
|
||||
* str_inout = NULL
|
||||
* file_rtrn = aliases
|
||||
* map_rtrn = qwerty
|
||||
* extra_data = NULL
|
||||
* nextop_retrn = ""
|
||||
*
|
||||
*/
|
||||
Bool
|
||||
XkbParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
|
||||
char *nextop_rtrn, char **extra_data)
|
||||
{
|
||||
char *tmp, *str, *next;
|
||||
|
||||
str = *str_inout;
|
||||
if ((*str == '+') || (*str == '|'))
|
||||
{
|
||||
*file_rtrn = *map_rtrn = NULL;
|
||||
*nextop_rtrn = *str;
|
||||
next = str + 1;
|
||||
}
|
||||
else if (*str == '%')
|
||||
{
|
||||
*file_rtrn = *map_rtrn = NULL;
|
||||
*nextop_rtrn = str[1];
|
||||
next = str + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* search for tokens inside the string */
|
||||
next = strpbrk(str, "|+");
|
||||
if (next)
|
||||
{
|
||||
/* set nextop_rtrn to \0, next to next character */
|
||||
*nextop_rtrn = *next;
|
||||
*next++ = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
*nextop_rtrn = '\0';
|
||||
next = NULL;
|
||||
}
|
||||
/* search for :, store result in extra_data */
|
||||
tmp = strchr(str, ':');
|
||||
if (tmp != NULL)
|
||||
{
|
||||
*tmp++ = '\0';
|
||||
*extra_data = uStringDup(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
*extra_data = NULL;
|
||||
}
|
||||
tmp = strchr(str, '(');
|
||||
if (tmp == NULL)
|
||||
{
|
||||
*file_rtrn = uStringDup(str);
|
||||
*map_rtrn = NULL;
|
||||
}
|
||||
else if (str[0] == '(')
|
||||
{
|
||||
uFree(*extra_data);
|
||||
return False;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp++ = '\0';
|
||||
*file_rtrn = uStringDup(str);
|
||||
str = tmp;
|
||||
tmp = strchr(str, ')');
|
||||
if ((tmp == NULL) || (tmp[1] != '\0'))
|
||||
{
|
||||
uFree(*file_rtrn);
|
||||
uFree(*extra_data);
|
||||
return False;
|
||||
}
|
||||
*tmp++ = '\0';
|
||||
*map_rtrn = uStringDup(str);
|
||||
}
|
||||
}
|
||||
if (*nextop_rtrn == '\0')
|
||||
*str_inout = NULL;
|
||||
else if ((*nextop_rtrn == '|') || (*nextop_rtrn == '+'))
|
||||
*str_inout = next;
|
||||
else
|
||||
return False;
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init memory for include paths.
|
||||
*/
|
||||
Bool
|
||||
XkbInitIncludePath(void)
|
||||
{
|
||||
szPath = PATH_CHUNK;
|
||||
includePath = (char **) calloc(szPath, sizeof(char *));
|
||||
if (includePath == NULL)
|
||||
return False;
|
||||
return True;
|
||||
}
|
||||
|
||||
void
|
||||
XkbAddDefaultDirectoriesToPath(void)
|
||||
{
|
||||
if (noDefaultPath)
|
||||
return;
|
||||
XkbAddDirectoryToPath(DFLT_XKB_CONFIG_ROOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the global includePath.
|
||||
*/
|
||||
void
|
||||
XkbClearIncludePath(void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (szPath > 0)
|
||||
{
|
||||
for (i = 0; i < nPathEntries; i++)
|
||||
{
|
||||
if (includePath[i] != NULL)
|
||||
{
|
||||
uFree(includePath[i]);
|
||||
includePath[i] = NULL;
|
||||
}
|
||||
}
|
||||
nPathEntries = 0;
|
||||
}
|
||||
noDefaultPath = True;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given path to the global includePath variable.
|
||||
* If dir is NULL, the includePath is emptied.
|
||||
*/
|
||||
Bool
|
||||
XkbAddDirectoryToPath(const char *dir)
|
||||
{
|
||||
int len;
|
||||
if ((dir == NULL) || (dir[0] == '\0'))
|
||||
{
|
||||
XkbClearIncludePath();
|
||||
return True;
|
||||
}
|
||||
#ifdef __UNIXOS2__
|
||||
dir = (char *) __XOS2RedirRoot(dir);
|
||||
#endif
|
||||
len = strlen(dir);
|
||||
if (len + 2 >= PATH_MAX)
|
||||
{ /* allow for '/' and at least one character */
|
||||
ERROR2("Path entry (%s) too long (maxiumum length is %d)\n",
|
||||
dir, PATH_MAX - 3);
|
||||
return False;
|
||||
}
|
||||
if (nPathEntries >= szPath)
|
||||
{
|
||||
szPath += PATH_CHUNK;
|
||||
includePath = (char **) realloc(includePath, szPath * sizeof(char *));
|
||||
if (includePath == NULL)
|
||||
{
|
||||
WSGO("Allocation failed (includePath)\n");
|
||||
return False;
|
||||
}
|
||||
}
|
||||
includePath[nPathEntries] =
|
||||
(char *) calloc(strlen(dir) + 1, sizeof(char));
|
||||
if (includePath[nPathEntries] == NULL)
|
||||
{
|
||||
WSGO1("Allocation failed (includePath[%d])\n", nPathEntries);
|
||||
return False;
|
||||
}
|
||||
strcpy(includePath[nPathEntries++], dir);
|
||||
return True;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
/**
|
||||
* Return the xkb directory based on the type.
|
||||
* Do not free the memory returned by this function.
|
||||
*/
|
||||
char *
|
||||
XkbDirectoryForInclude(unsigned type)
|
||||
{
|
||||
static char buf[32];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case XkmSemanticsFile:
|
||||
strcpy(buf, "semantics");
|
||||
break;
|
||||
case XkmLayoutFile:
|
||||
strcpy(buf, "layout");
|
||||
break;
|
||||
case XkmKeymapFile:
|
||||
strcpy(buf, "keymap");
|
||||
break;
|
||||
case XkmKeyNamesIndex:
|
||||
strcpy(buf, "keycodes");
|
||||
break;
|
||||
case XkmTypesIndex:
|
||||
strcpy(buf, "types");
|
||||
break;
|
||||
case XkmSymbolsIndex:
|
||||
strcpy(buf, "symbols");
|
||||
break;
|
||||
case XkmCompatMapIndex:
|
||||
strcpy(buf, "compat");
|
||||
break;
|
||||
case XkmGeometryFile:
|
||||
case XkmGeometryIndex:
|
||||
strcpy(buf, "geometry");
|
||||
break;
|
||||
default:
|
||||
strcpy(buf, "");
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
typedef struct _FileCacheEntry
|
||||
{
|
||||
char *name;
|
||||
unsigned type;
|
||||
char *path;
|
||||
void *data;
|
||||
struct _FileCacheEntry *next;
|
||||
} FileCacheEntry;
|
||||
static FileCacheEntry *fileCache;
|
||||
|
||||
/**
|
||||
* Add the file with the given name to the internal cache to avoid opening and
|
||||
* parsing the file multiple times. If a cache entry for the same name + type
|
||||
* is already present, the entry is overwritten and the data belonging to the
|
||||
* previous entry is returned.
|
||||
*
|
||||
* @parameter name The name of the file (e.g. evdev).
|
||||
* @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...)
|
||||
* @parameter path The full path to the file.
|
||||
* @parameter data Already parsed data.
|
||||
*
|
||||
* @return The data from the overwritten file or NULL.
|
||||
*/
|
||||
void *
|
||||
XkbAddFileToCache(char *name, unsigned type, char *path, void *data)
|
||||
{
|
||||
FileCacheEntry *entry;
|
||||
|
||||
for (entry = fileCache; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if ((type == entry->type) && (uStringEqual(name, entry->name)))
|
||||
{
|
||||
void *old = entry->data;
|
||||
WSGO2("Replacing file cache entry (%s/%d)\n", name, type);
|
||||
entry->path = path;
|
||||
entry->data = data;
|
||||
return old;
|
||||
}
|
||||
}
|
||||
entry = uTypedAlloc(FileCacheEntry);
|
||||
if (entry != NULL)
|
||||
{
|
||||
entry->name = name;
|
||||
entry->type = type;
|
||||
entry->path = path;
|
||||
entry->data = data;
|
||||
entry->next = fileCache;
|
||||
fileCache = entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the given name + type in the cache.
|
||||
*
|
||||
* @parameter name The name of the file (e.g. evdev).
|
||||
* @parameter type Type of the file (XkbTypesIdx, ... or XkbSemanticsFile, ...)
|
||||
* @parameter pathRtrn Set to the full path of the given entry.
|
||||
*
|
||||
* @return the data from the cache entry or NULL if no matching entry was found.
|
||||
*/
|
||||
void *
|
||||
XkbFindFileInCache(char *name, unsigned type, char **pathRtrn)
|
||||
{
|
||||
FileCacheEntry *entry;
|
||||
|
||||
for (entry = fileCache; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if ((type == entry->type) && (uStringEqual(name, entry->name)))
|
||||
{
|
||||
*pathRtrn = entry->path;
|
||||
return entry->data;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
/**
|
||||
* Search for the given file name in the include directories.
|
||||
*
|
||||
* @param type one of XkbTypesIndex, XkbCompatMapIndex, ..., or
|
||||
* XkbSemanticsFile, XkmKeymapFile, ...
|
||||
* @param pathReturn is set to the full path of the file if found.
|
||||
*
|
||||
* @return an FD to the file or NULL. If NULL is returned, the value of
|
||||
* pathRtrn is undefined.
|
||||
*/
|
||||
FILE *
|
||||
XkbFindFileInPath(char *name, unsigned type, char **pathRtrn)
|
||||
{
|
||||
register int i;
|
||||
FILE *file = NULL;
|
||||
int nameLen, typeLen, pathLen;
|
||||
char buf[PATH_MAX], *typeDir;
|
||||
|
||||
typeDir = XkbDirectoryForInclude(type);
|
||||
nameLen = strlen(name);
|
||||
typeLen = strlen(typeDir);
|
||||
for (i = 0; i < nPathEntries; i++)
|
||||
{
|
||||
pathLen = strlen(includePath[i]);
|
||||
if (typeLen < 1)
|
||||
continue;
|
||||
|
||||
if ((nameLen + typeLen + pathLen + 2) >= PATH_MAX)
|
||||
{
|
||||
ERROR3("File name (%s/%s/%s) too long\n", includePath[i],
|
||||
typeDir, name);
|
||||
ACTION("Ignored\n");
|
||||
continue;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s/%s/%s", includePath[i], typeDir, name);
|
||||
file = fopen(buf, "r");
|
||||
if (file != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((file != NULL) && (pathRtrn != NULL))
|
||||
{
|
||||
*pathRtrn = (char *) calloc(strlen(buf) + 1, sizeof(char));
|
||||
if (*pathRtrn != NULL)
|
||||
strcpy(*pathRtrn, buf);
|
||||
}
|
||||
return file;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifndef _XKBPATH_H_
|
||||
#define _XKBPATH_H_ 1
|
||||
|
||||
extern Bool XkbInitIncludePath(void);
|
||||
|
||||
extern void XkbClearIncludePath(void);
|
||||
|
||||
extern void XkbAddDefaultDirectoriesToPath(void);
|
||||
|
||||
extern Bool XkbAddDirectoryToPath(const char * /* dir */
|
||||
);
|
||||
|
||||
extern char *XkbDirectoryForInclude(unsigned /* type */
|
||||
);
|
||||
|
||||
extern FILE *XkbFindFileInPath(char * /* name */ ,
|
||||
unsigned /* type */ ,
|
||||
char ** /* pathRtrn */
|
||||
);
|
||||
|
||||
extern void *XkbAddFileToCache(char * /* name */ ,
|
||||
unsigned /* type */ ,
|
||||
char * /* path */ ,
|
||||
void * /* data */
|
||||
);
|
||||
|
||||
extern void *XkbFindFileInCache(char * /* name */ ,
|
||||
unsigned /* type */ ,
|
||||
char ** /* pathRtrn */
|
||||
);
|
||||
|
||||
extern Bool XkbParseIncludeMap(char ** /* str_inout */ ,
|
||||
char ** /* file_rtrn */ ,
|
||||
char ** /* map_rtrn */ ,
|
||||
char * /* nextop_rtrn */ ,
|
||||
char ** /* extra_data */
|
||||
);
|
||||
|
||||
#endif /* _XKBPATH_H_ */
|
|
@ -0,0 +1,723 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "tokens.h"
|
||||
#define DEBUG_VAR scanDebug
|
||||
#include "utils.h"
|
||||
#include "parseutils.h"
|
||||
|
||||
unsigned int scanDebug;
|
||||
|
||||
FILE *yyin = NULL;
|
||||
|
||||
static char scanFileBuf[1024] = {0};
|
||||
char *scanFile = scanFileBuf;
|
||||
int lineNum = 0;
|
||||
|
||||
int scanInt;
|
||||
|
||||
char *scanStr = NULL;
|
||||
static int scanStrLine = 0;
|
||||
|
||||
#define BUFSIZE 512
|
||||
static int nInBuf = 0;
|
||||
static char buf[BUFSIZE];
|
||||
|
||||
#ifdef DEBUG
|
||||
static char *
|
||||
tokText(int tok)
|
||||
{
|
||||
static char buf[32];
|
||||
|
||||
switch (tok)
|
||||
{
|
||||
case END_OF_FILE:
|
||||
snprintf(buf, sizeof(buf), "END_OF_FILE");
|
||||
break;
|
||||
case ERROR_TOK:
|
||||
snprintf(buf, sizeof(buf), "ERROR");
|
||||
break;
|
||||
|
||||
case XKB_KEYMAP:
|
||||
snprintf(buf, sizeof(buf), "XKB_KEYMAP");
|
||||
break;
|
||||
case XKB_KEYCODES:
|
||||
snprintf(buf, sizeof(buf), "XKB_KEYCODES");
|
||||
break;
|
||||
case XKB_TYPES:
|
||||
snprintf(buf, sizeof(buf), "XKB_TYPES");
|
||||
break;
|
||||
case XKB_SYMBOLS:
|
||||
snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
|
||||
break;
|
||||
case XKB_COMPATMAP:
|
||||
snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
|
||||
break;
|
||||
case XKB_GEOMETRY:
|
||||
snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
|
||||
break;
|
||||
case XKB_SEMANTICS:
|
||||
snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
|
||||
break;
|
||||
case XKB_LAYOUT:
|
||||
snprintf(buf, sizeof(buf), "XKB_LAYOUT");
|
||||
break;
|
||||
|
||||
case INCLUDE:
|
||||
snprintf(buf, sizeof(buf), "INCLUDE");
|
||||
break;
|
||||
case OVERRIDE:
|
||||
snprintf(buf, sizeof(buf), "OVERRIDE");
|
||||
break;
|
||||
case AUGMENT:
|
||||
snprintf(buf, sizeof(buf), "AUGMENT");
|
||||
break;
|
||||
case REPLACE:
|
||||
snprintf(buf, sizeof(buf), "REPLACE");
|
||||
break;
|
||||
case ALTERNATE:
|
||||
snprintf(buf, sizeof(buf), "ALTERNATE");
|
||||
break;
|
||||
|
||||
case VIRTUAL_MODS:
|
||||
snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
|
||||
break;
|
||||
case TYPE:
|
||||
snprintf(buf, sizeof(buf), "TYPE");
|
||||
break;
|
||||
case INTERPRET:
|
||||
snprintf(buf, sizeof(buf), "INTERPRET");
|
||||
break;
|
||||
case ACTION_TOK:
|
||||
snprintf(buf, sizeof(buf), "ACTION");
|
||||
break;
|
||||
case KEY:
|
||||
snprintf(buf, sizeof(buf), "KEY");
|
||||
break;
|
||||
case ALIAS:
|
||||
snprintf(buf, sizeof(buf), "ALIAS");
|
||||
break;
|
||||
case GROUP:
|
||||
snprintf(buf, sizeof(buf), "GROUP");
|
||||
break;
|
||||
case MODIFIER_MAP:
|
||||
snprintf(buf, sizeof(buf), "MODIFIER_MAP");
|
||||
break;
|
||||
case INDICATOR:
|
||||
snprintf(buf, sizeof(buf), "INDICATOR");
|
||||
break;
|
||||
case SHAPE:
|
||||
snprintf(buf, sizeof(buf), "SHAPE");
|
||||
break;
|
||||
case KEYS:
|
||||
snprintf(buf, sizeof(buf), "KEYS");
|
||||
break;
|
||||
case ROW:
|
||||
snprintf(buf, sizeof(buf), "ROW");
|
||||
break;
|
||||
case SECTION:
|
||||
snprintf(buf, sizeof(buf), "SECTION");
|
||||
break;
|
||||
case OVERLAY:
|
||||
snprintf(buf, sizeof(buf), "OVERLAY");
|
||||
break;
|
||||
case TEXT:
|
||||
snprintf(buf, sizeof(buf), "TEXT");
|
||||
break;
|
||||
case OUTLINE:
|
||||
snprintf(buf, sizeof(buf), "OUTLINE");
|
||||
break;
|
||||
case SOLID:
|
||||
snprintf(buf, sizeof(buf), "SOLID");
|
||||
break;
|
||||
case LOGO:
|
||||
snprintf(buf, sizeof(buf), "LOGO");
|
||||
break;
|
||||
case VIRTUAL:
|
||||
snprintf(buf, sizeof(buf), "VIRTUAL");
|
||||
break;
|
||||
|
||||
case EQUALS:
|
||||
snprintf(buf, sizeof(buf), "EQUALS");
|
||||
break;
|
||||
case PLUS:
|
||||
snprintf(buf, sizeof(buf), "PLUS");
|
||||
break;
|
||||
case MINUS:
|
||||
snprintf(buf, sizeof(buf), "MINUS");
|
||||
break;
|
||||
case DIVIDE:
|
||||
snprintf(buf, sizeof(buf), "DIVIDE");
|
||||
break;
|
||||
case TIMES:
|
||||
snprintf(buf, sizeof(buf), "TIMES");
|
||||
break;
|
||||
case OBRACE:
|
||||
snprintf(buf, sizeof(buf), "OBRACE");
|
||||
break;
|
||||
case CBRACE:
|
||||
snprintf(buf, sizeof(buf), "CBRACE");
|
||||
break;
|
||||
case OPAREN:
|
||||
snprintf(buf, sizeof(buf), "OPAREN");
|
||||
break;
|
||||
case CPAREN:
|
||||
snprintf(buf, sizeof(buf), "CPAREN");
|
||||
break;
|
||||
case OBRACKET:
|
||||
snprintf(buf, sizeof(buf), "OBRACKET");
|
||||
break;
|
||||
case CBRACKET:
|
||||
snprintf(buf, sizeof(buf), "CBRACKET");
|
||||
break;
|
||||
case DOT:
|
||||
snprintf(buf, sizeof(buf), "DOT");
|
||||
break;
|
||||
case COMMA:
|
||||
snprintf(buf, sizeof(buf), "COMMA");
|
||||
break;
|
||||
case SEMI:
|
||||
snprintf(buf, sizeof(buf), "SEMI");
|
||||
break;
|
||||
case EXCLAM:
|
||||
snprintf(buf, sizeof(buf), "EXCLAM");
|
||||
break;
|
||||
case INVERT:
|
||||
snprintf(buf, sizeof(buf), "INVERT");
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
snprintf(buf, sizeof(buf), "STRING (%s)", scanStr);
|
||||
break;
|
||||
case INTEGER:
|
||||
snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
|
||||
break;
|
||||
case FLOAT:
|
||||
snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
|
||||
scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
|
||||
break;
|
||||
case IDENT:
|
||||
snprintf(buf, sizeof(buf), "IDENT (%s)", scanStr);
|
||||
break;
|
||||
case KEYNAME:
|
||||
snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanStr);
|
||||
break;
|
||||
|
||||
case PARTIAL:
|
||||
snprintf(buf, sizeof(buf), "PARTIAL");
|
||||
break;
|
||||
case DEFAULT:
|
||||
snprintf(buf, sizeof(buf), "DEFAULT");
|
||||
break;
|
||||
case HIDDEN:
|
||||
snprintf(buf, sizeof(buf), "HIDDEN");
|
||||
break;
|
||||
|
||||
case ALPHANUMERIC_KEYS:
|
||||
snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
|
||||
break;
|
||||
case MODIFIER_KEYS:
|
||||
snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
|
||||
break;
|
||||
case KEYPAD_KEYS:
|
||||
snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
|
||||
break;
|
||||
case FUNCTION_KEYS:
|
||||
snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
|
||||
break;
|
||||
case ALTERNATE_GROUP:
|
||||
snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "UNKNOWN");
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
setScanState(char *file, int line)
|
||||
{
|
||||
if (file != NULL)
|
||||
strncpy(scanFile, file, 1024);
|
||||
if (line >= 0)
|
||||
lineNum = line;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
yyGetString(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
nInBuf = 0;
|
||||
while (((ch = getc(yyin)) != EOF) && (ch != '"'))
|
||||
{
|
||||
if (ch == '\\')
|
||||
{
|
||||
if ((ch = getc(yyin)) != EOF)
|
||||
{
|
||||
if (ch == 'n')
|
||||
ch = '\n';
|
||||
else if (ch == 't')
|
||||
ch = '\t';
|
||||
else if (ch == 'v')
|
||||
ch = '\v';
|
||||
else if (ch == 'b')
|
||||
ch = '\b';
|
||||
else if (ch == 'r')
|
||||
ch = '\r';
|
||||
else if (ch == 'f')
|
||||
ch = '\f';
|
||||
else if (ch == 'e')
|
||||
ch = '\033';
|
||||
else if (ch == '0')
|
||||
{
|
||||
int tmp, stop;
|
||||
ch = stop = 0;
|
||||
if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
|
||||
&& (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
if (!stop)
|
||||
{
|
||||
if (((tmp = getc(yyin)) != EOF)
|
||||
&& (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
}
|
||||
if (!stop)
|
||||
{
|
||||
if (((tmp = getc(yyin)) != EOF)
|
||||
&& (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return ERROR_TOK;
|
||||
}
|
||||
if (nInBuf < BUFSIZE - 1)
|
||||
buf[nInBuf++] = ch;
|
||||
}
|
||||
if (ch == '"')
|
||||
{
|
||||
buf[nInBuf++] = '\0';
|
||||
if (scanStr)
|
||||
uFree(scanStr);
|
||||
scanStr = (char *) uStringDup(buf);
|
||||
scanStrLine = lineNum;
|
||||
return STRING;
|
||||
}
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
static int
|
||||
yyGetKeyName(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
nInBuf = 0;
|
||||
while (((ch = getc(yyin)) != EOF) && (ch != '>'))
|
||||
{
|
||||
if (ch == '\\')
|
||||
{
|
||||
if ((ch = getc(yyin)) != EOF)
|
||||
{
|
||||
if (ch == 'n')
|
||||
ch = '\n';
|
||||
else if (ch == 't')
|
||||
ch = '\t';
|
||||
else if (ch == 'v')
|
||||
ch = '\v';
|
||||
else if (ch == 'b')
|
||||
ch = '\b';
|
||||
else if (ch == 'r')
|
||||
ch = '\r';
|
||||
else if (ch == 'f')
|
||||
ch = '\f';
|
||||
else if (ch == 'e')
|
||||
ch = '\033';
|
||||
else if (ch == '0')
|
||||
{
|
||||
int tmp, stop;
|
||||
ch = stop = 0;
|
||||
if (((tmp = getc(yyin)) != EOF) && (isdigit(tmp))
|
||||
&& (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
if ((!stop) && ((tmp = getc(yyin)) != EOF)
|
||||
&& (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
if ((!stop) && ((tmp = getc(yyin)) != EOF)
|
||||
&& (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
|
||||
{
|
||||
ch = (ch * 8) + (tmp - '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = 1;
|
||||
ungetc(tmp, yyin);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
if (nInBuf < BUFSIZE - 1)
|
||||
buf[nInBuf++] = ch;
|
||||
}
|
||||
if ((ch == '>') && (nInBuf < 5))
|
||||
{
|
||||
buf[nInBuf++] = '\0';
|
||||
if (scanStr)
|
||||
uFree(scanStr);
|
||||
scanStr = (char *) uStringDup(buf);
|
||||
scanStrLine = lineNum;
|
||||
return KEYNAME;
|
||||
}
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
static struct _Keyword
|
||||
{
|
||||
const char *keyword;
|
||||
int token;
|
||||
} keywords[] =
|
||||
{
|
||||
{
|
||||
"xkb_keymap", XKB_KEYMAP},
|
||||
{
|
||||
"xkb_keycodes", XKB_KEYCODES},
|
||||
{
|
||||
"xkb_types", XKB_TYPES},
|
||||
{
|
||||
"xkb_symbols", XKB_SYMBOLS},
|
||||
{
|
||||
"xkb_compat", XKB_COMPATMAP},
|
||||
{
|
||||
"xkb_compat_map", XKB_COMPATMAP},
|
||||
{
|
||||
"xkb_compatibility", XKB_COMPATMAP},
|
||||
{
|
||||
"xkb_compatibility_map", XKB_COMPATMAP},
|
||||
{
|
||||
"xkb_geometry", XKB_GEOMETRY},
|
||||
{
|
||||
"xkb_semantics", XKB_SEMANTICS},
|
||||
{
|
||||
"xkb_layout", XKB_LAYOUT},
|
||||
{
|
||||
"include", INCLUDE},
|
||||
{
|
||||
"override", OVERRIDE},
|
||||
{
|
||||
"augment", AUGMENT},
|
||||
{
|
||||
"replace", REPLACE},
|
||||
{
|
||||
"alternate", ALTERNATE},
|
||||
{
|
||||
"partial", PARTIAL},
|
||||
{
|
||||
"default", DEFAULT},
|
||||
{
|
||||
"hidden", HIDDEN},
|
||||
{
|
||||
"virtual_modifiers", VIRTUAL_MODS},
|
||||
{
|
||||
"type", TYPE},
|
||||
{
|
||||
"interpret", INTERPRET},
|
||||
{
|
||||
"action", ACTION_TOK},
|
||||
{
|
||||
"key", KEY},
|
||||
{
|
||||
"alias", ALIAS},
|
||||
{
|
||||
"group", GROUP},
|
||||
{
|
||||
"modmap", MODIFIER_MAP},
|
||||
{
|
||||
"mod_map", MODIFIER_MAP},
|
||||
{
|
||||
"modifier_map", MODIFIER_MAP},
|
||||
{
|
||||
"indicator", INDICATOR},
|
||||
{
|
||||
"shape", SHAPE},
|
||||
{
|
||||
"row", ROW},
|
||||
{
|
||||
"keys", KEYS},
|
||||
{
|
||||
"section", SECTION},
|
||||
{
|
||||
"overlay", OVERLAY},
|
||||
{
|
||||
"text", TEXT},
|
||||
{
|
||||
"outline", OUTLINE},
|
||||
{
|
||||
"solid", SOLID},
|
||||
{
|
||||
"logo", LOGO},
|
||||
{
|
||||
"virtual", VIRTUAL},
|
||||
{
|
||||
"alphanumeric_keys", ALPHANUMERIC_KEYS},
|
||||
{
|
||||
"modifier_keys", MODIFIER_KEYS},
|
||||
{
|
||||
"keypad_keys", KEYPAD_KEYS},
|
||||
{
|
||||
"function_keys", FUNCTION_KEYS},
|
||||
{
|
||||
"alternate_group", ALTERNATE_GROUP}
|
||||
};
|
||||
static int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
|
||||
|
||||
static int
|
||||
yyGetIdent(int first)
|
||||
{
|
||||
int ch, i, found;
|
||||
int rtrn = IDENT;
|
||||
|
||||
buf[0] = first;
|
||||
nInBuf = 1;
|
||||
while (((ch = getc(yyin)) != EOF) && (isalnum(ch) || (ch == '_')))
|
||||
{
|
||||
if (nInBuf < BUFSIZE - 1)
|
||||
buf[nInBuf++] = ch;
|
||||
}
|
||||
buf[nInBuf++] = '\0';
|
||||
found = 0;
|
||||
|
||||
for (i = 0; (!found) && (i < numKeywords); i++)
|
||||
{
|
||||
if (uStrCaseCmp(buf, keywords[i].keyword) == 0)
|
||||
{
|
||||
rtrn = keywords[i].token;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
if (scanStr)
|
||||
uFree(scanStr);
|
||||
scanStr = (char *) uStringDup(buf);
|
||||
scanStrLine = lineNum;
|
||||
rtrn = IDENT;
|
||||
}
|
||||
|
||||
if ((ch != EOF) && (!isspace(ch)))
|
||||
ungetc(ch, yyin);
|
||||
else if (ch == '\n')
|
||||
lineNum++;
|
||||
|
||||
return rtrn;
|
||||
}
|
||||
|
||||
static int
|
||||
yyGetNumber(int ch)
|
||||
{
|
||||
int isFloat = 0;
|
||||
|
||||
buf[0] = ch;
|
||||
nInBuf = 1;
|
||||
while (((ch = getc(yyin)) != EOF)
|
||||
&& (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x'))))
|
||||
{
|
||||
buf[nInBuf++] = ch;
|
||||
}
|
||||
if (ch == '.')
|
||||
{
|
||||
isFloat = 1;
|
||||
buf[nInBuf++] = ch;
|
||||
while (((ch = getc(yyin)) != EOF) && (isxdigit(ch)))
|
||||
{
|
||||
buf[nInBuf++] = ch;
|
||||
}
|
||||
}
|
||||
buf[nInBuf++] = '\0';
|
||||
if ((ch != EOF) && (!isspace(ch)))
|
||||
ungetc(ch, yyin);
|
||||
|
||||
if (isFloat)
|
||||
{
|
||||
float tmp;
|
||||
if (sscanf(buf, "%g", &tmp) == 1)
|
||||
{
|
||||
scanInt = tmp * XkbGeomPtsPerMM;
|
||||
return FLOAT;
|
||||
}
|
||||
}
|
||||
else if (sscanf(buf, "%i", &scanInt) == 1)
|
||||
return INTEGER;
|
||||
fprintf(stderr, "Malformed number %s\n", buf);
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
int
|
||||
yylex(void)
|
||||
{
|
||||
int ch;
|
||||
int rtrn;
|
||||
|
||||
do
|
||||
{
|
||||
ch = getc(yyin);
|
||||
if (ch == '\n')
|
||||
{
|
||||
lineNum++;
|
||||
}
|
||||
else if (ch == '#')
|
||||
{ /* handle shell style '#' comments */
|
||||
do
|
||||
{
|
||||
ch = getc(yyin);
|
||||
}
|
||||
while ((ch != '\n') && (ch != EOF));
|
||||
lineNum++;
|
||||
}
|
||||
else if (ch == '/')
|
||||
{ /* handle C++ style double-/ comments */
|
||||
int newch = getc(yyin);
|
||||
if (newch == '/')
|
||||
{
|
||||
do
|
||||
{
|
||||
ch = getc(yyin);
|
||||
}
|
||||
while ((ch != '\n') && (ch != EOF));
|
||||
lineNum++;
|
||||
}
|
||||
else if (newch != EOF)
|
||||
{
|
||||
ungetc(newch, yyin);
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((ch != EOF) && (isspace(ch)));
|
||||
if (ch == '=')
|
||||
rtrn = EQUALS;
|
||||
else if (ch == '+')
|
||||
rtrn = PLUS;
|
||||
else if (ch == '-')
|
||||
rtrn = MINUS;
|
||||
else if (ch == '/')
|
||||
rtrn = DIVIDE;
|
||||
else if (ch == '*')
|
||||
rtrn = TIMES;
|
||||
else if (ch == '{')
|
||||
rtrn = OBRACE;
|
||||
else if (ch == '}')
|
||||
rtrn = CBRACE;
|
||||
else if (ch == '(')
|
||||
rtrn = OPAREN;
|
||||
else if (ch == ')')
|
||||
rtrn = CPAREN;
|
||||
else if (ch == '[')
|
||||
rtrn = OBRACKET;
|
||||
else if (ch == ']')
|
||||
rtrn = CBRACKET;
|
||||
else if (ch == '.')
|
||||
rtrn = DOT;
|
||||
else if (ch == ',')
|
||||
rtrn = COMMA;
|
||||
else if (ch == ';')
|
||||
rtrn = SEMI;
|
||||
else if (ch == '!')
|
||||
rtrn = EXCLAM;
|
||||
else if (ch == '~')
|
||||
rtrn = INVERT;
|
||||
else if (ch == '"')
|
||||
rtrn = yyGetString();
|
||||
else if (ch == '<')
|
||||
rtrn = yyGetKeyName();
|
||||
else if (isalpha(ch) || (ch == '_'))
|
||||
rtrn = yyGetIdent(ch);
|
||||
else if (isdigit(ch))
|
||||
rtrn = yyGetNumber(ch);
|
||||
else if (ch == EOF)
|
||||
rtrn = END_OF_FILE;
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (debugFlags)
|
||||
fprintf(stderr,
|
||||
"Unexpected character %c (%d) in input stream\n", ch, ch);
|
||||
#endif
|
||||
rtrn = ERROR_TOK;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (debugFlags & 0x2)
|
||||
fprintf(stderr, "scan: %s\n", tokText(rtrn));
|
||||
#endif
|
||||
return rtrn;
|
||||
}
|
Loading…
Reference in New Issue