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
Dan Nicholson 2009-03-27 06:55:32 -07:00
parent f4d8e2932c
commit 0c1bbb05d9
35 changed files with 22364 additions and 7 deletions

View File

@ -29,6 +29,7 @@ AC_CONFIG_HEADERS([src/config.h])
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_CC AC_PROG_CC
AC_PROG_YACC
m4_ifndef([PKG_PROG_PKG_CONFIG], m4_ifndef([PKG_PROG_PKG_CONFIG],
[m4_fatal([Could not locate the pkg-config autoconf macros. [m4_fatal([Could not locate the pkg-config autoconf macros.
@ -38,6 +39,11 @@ m4_ifndef([PKG_PROG_PKG_CONFIG],
autoreconf/autogen.sh.])]) autoreconf/autogen.sh.])])
PKG_PROG_PKG_CONFIG 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 dnl Build native compiler needed for makekeys
AC_ARG_VAR([CC_FOR_BUILD], [Build native C compiler program]) AC_ARG_VAR([CC_FOR_BUILD], [Build native C compiler program])
if test "x$CC_FOR_BUILD" = x; then if test "x$CC_FOR_BUILD" = x; then
@ -48,6 +54,10 @@ if test "x$CC_FOR_BUILD" = x; then
fi fi
fi fi
AC_CHECK_FUNCS([strdup strcasecmp])
XORG_CHECK_MALLOC_ZERO
XORG_CWARNFLAGS
PKG_CHECK_MODULES([X11], [xproto kbproto >= 1.0.99.1]) PKG_CHECK_MODULES([X11], [xproto kbproto >= 1.0.99.1])
dnl Ensure we have keysym headers dnl Ensure we have keysym headers
@ -69,13 +79,14 @@ AC_SUBST([XF86KEYSYM_H])
AC_SUBST([KS_HEADERS], ['$(KEYSYMDEF_H) $(XF86KEYSYM_H)']) AC_SUBST([KS_HEADERS], ['$(KEYSYMDEF_H) $(XF86KEYSYM_H)'])
# Require xorg-macros version 1.2.0 or newer for XORG_CHANGELOG macro AC_ARG_WITH([xkb_config_root],
m4_ifndef([XORG_MACROS_VERSION], [AC_HELP_STRING([--with-xkb-config-root=<paths>],
[m4_fatal([must install xorg-macros before running autoconf/autogen.sh])]) [Set default XKB config root (default: ${datadir}/X11/xkb)])],
XORG_MACROS_VERSION([1.2.0]) [XKBCONFIGROOT="$withval"],
[XKBCONFIGROOT='${datadir}/X11/xkb'])
AC_SUBST([XKBCONFIGROOT])
XORG_RELEASE_VERSION XORG_RELEASE_VERSION
XORG_CHECK_MALLOC_ZERO
XORG_CWARNFLAGS
XORG_CHANGELOG XORG_CHANGELOG
AC_OUTPUT([ AC_OUTPUT([
@ -83,5 +94,6 @@ Makefile
include/Makefile include/Makefile
src/Makefile src/Makefile
src/makekeys/Makefile src/makekeys/Makefile
src/xkbcomp/Makefile
test/Makefile test/Makefile
]) ])

View File

@ -1,9 +1,10 @@
SUBDIRS = makekeys SUBDIRS = makekeys xkbcomp
INCLUDES = -I$(top_srcdir)/include -I$(builddir)/makekeys INCLUDES = -I$(top_srcdir)/include -I$(builddir)/makekeys
AM_CFLAGS = $(X11_CFLAGS) $(CWARNFLAGS) $(XMALLOC_ZERO_CFLAGS) AM_CFLAGS = $(X11_CFLAGS) $(CWARNFLAGS) $(XMALLOC_ZERO_CFLAGS)
lib_LTLIBRARIES = libxkbcommon.la lib_LTLIBRARIES = libxkbcommon.la
libxkbcommon_la_LIBADD = xkbcomp/libxkbcomp.la
libxkbcommon_la_SOURCES = \ libxkbcommon_la_SOURCES = \
XKBcommonint.h \ XKBcommonint.h \
alloc.c \ alloc.c \

40
src/xkbcomp/Makefile.am Normal file
View File

@ -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

1468
src/xkbcomp/action.c Normal file

File diff suppressed because it is too large Load Diff

86
src/xkbcomp/action.h Normal file
View File

@ -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 */

289
src/xkbcomp/alias.c Normal file
View File

@ -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;
}

56
src/xkbcomp/alias.h Normal file
View File

@ -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 */

880
src/xkbcomp/compat.c Normal file
View File

@ -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;
}

7
src/xkbcomp/compat.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef COMPAT_H
#define COMPAT_H 1
extern LookupEntry groupNames[];
#endif /* COMPAT_H */

1065
src/xkbcomp/expr.c Normal file

File diff suppressed because it is too large Load Diff

172
src/xkbcomp/expr.h Normal file
View File

@ -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 */

3768
src/xkbcomp/geometry.c Normal file

File diff suppressed because it is too large Load Diff

575
src/xkbcomp/indicators.c Normal file
View File

@ -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;
}

88
src/xkbcomp/indicators.h Normal file
View File

@ -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 */

896
src/xkbcomp/keycodes.c Normal file
View File

@ -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;
}

40
src/xkbcomp/keycodes.h Normal file
View File

@ -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 */

183
src/xkbcomp/keymap.c Normal file
View File

@ -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;
}

1293
src/xkbcomp/keytypes.c Normal file

File diff suppressed because it is too large Load Diff

495
src/xkbcomp/listing.c Normal file
View File

@ -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;
}

576
src/xkbcomp/misc.c Normal file
View File

@ -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;
}

111
src/xkbcomp/misc.h Normal file
View File

@ -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 */

834
src/xkbcomp/parseutils.c Normal file
View File

@ -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;
}

208
src/xkbcomp/parseutils.h Normal file
View File

@ -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 */

2301
src/xkbcomp/symbols.c Normal file

File diff suppressed because it is too large Load Diff

104
src/xkbcomp/tokens.h Normal file
View File

@ -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

434
src/xkbcomp/utils.c Normal file
View File

@ -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

381
src/xkbcomp/utils.h Normal file
View File

@ -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 */

271
src/xkbcomp/vmod.c Normal file
View File

@ -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;
}

78
src/xkbcomp/vmod.h Normal file
View File

@ -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 */

396
src/xkbcomp/xkbcomp.h Normal file
View File

@ -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 */

3242
src/xkbcomp/xkbparse.c Normal file

File diff suppressed because it is too large Load Diff

799
src/xkbcomp/xkbparse.y Normal file
View File

@ -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;
}

420
src/xkbcomp/xkbpath.c Normal file
View File

@ -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;
}

65
src/xkbcomp/xkbpath.h Normal file
View 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_ */

723
src/xkbcomp/xkbscan.c Normal file
View File

@ -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;
}