diff options
Diffstat (limited to 'xkbcomp')
-rw-r--r-- | xkbcomp/.gitignore | 160 | ||||
-rw-r--r-- | xkbcomp/COPYING | 180 | ||||
-rw-r--r-- | xkbcomp/action.c | 2936 | ||||
-rw-r--r-- | xkbcomp/action.h | 172 | ||||
-rw-r--r-- | xkbcomp/alias.h | 112 | ||||
-rw-r--r-- | xkbcomp/autogen.sh | 26 | ||||
-rw-r--r-- | xkbcomp/compat.h | 14 | ||||
-rw-r--r-- | xkbcomp/expr.c | 2130 | ||||
-rw-r--r-- | xkbcomp/expr.h | 344 | ||||
-rw-r--r-- | xkbcomp/indicators.c | 1150 | ||||
-rw-r--r-- | xkbcomp/indicators.h | 176 | ||||
-rw-r--r-- | xkbcomp/keycodes.c | 1788 | ||||
-rw-r--r-- | xkbcomp/keycodes.h | 80 | ||||
-rw-r--r-- | xkbcomp/keymap.c | 366 | ||||
-rw-r--r-- | xkbcomp/keytypes.c | 2586 | ||||
-rw-r--r-- | xkbcomp/misc.c | 1162 | ||||
-rw-r--r-- | xkbcomp/misc.h | 222 | ||||
-rw-r--r-- | xkbcomp/tokens.h | 208 | ||||
-rw-r--r-- | xkbcomp/utils.c | 868 | ||||
-rw-r--r-- | xkbcomp/vmod.c | 542 | ||||
-rw-r--r-- | xkbcomp/vmod.h | 156 | ||||
-rw-r--r-- | xkbcomp/xkbpath.c | 840 | ||||
-rw-r--r-- | xkbcomp/xkbpath.h | 130 |
23 files changed, 8174 insertions, 8174 deletions
diff --git a/xkbcomp/.gitignore b/xkbcomp/.gitignore index 4b418d2a8..c6e344a28 100644 --- a/xkbcomp/.gitignore +++ b/xkbcomp/.gitignore @@ -1,80 +1,80 @@ -#
-# X.Org module default exclusion patterns
-# The next section if for module specific patterns
-#
-# Do not edit the following section
-# GNU Build System (Autotools)
-aclocal.m4
-autom4te.cache/
-autoscan.log
-ChangeLog
-compile
-config.guess
-config.h
-config.h.in
-config.log
-config-ml.in
-config.py
-config.status
-config.status.lineno
-config.sub
-configure
-configure.scan
-depcomp
-.deps/
-INSTALL
-install-sh
-.libs/
-libtool
-libtool.m4
-ltmain.sh
-lt~obsolete.m4
-ltoptions.m4
-ltsugar.m4
-ltversion.m4
-Makefile
-Makefile.in
-mdate-sh
-missing
-mkinstalldirs
-*.pc
-py-compile
-stamp-h?
-symlink-tree
-texinfo.tex
-ylwrap
-
-# Do not edit the following section
-# Edit Compile Debug Document Distribute
-*~
-*.[0-9]
-*.[0-9]x
-*.bak
-*.bin
-core
-*.dll
-*.exe
-*-ISO*.bdf
-*-JIS*.bdf
-*-KOI8*.bdf
-*.kld
-*.ko
-*.ko.cmd
-*.lai
-*.l[oa]
-*.[oa]
-*.obj
-*.patch
-*.so
-*.pcf.gz
-*.pdb
-*.tar.bz2
-*.tar.gz
-#
-# Add & Override patterns for xkbcomp
-#
-# Edit the following section as needed
-# For example, !report.pc overrides *.pc. See 'man gitignore'
-#
-xkbcomp
-xkbparse.c
+# +# X.Org module default exclusion patterns +# The next section if for module specific patterns +# +# Do not edit the following section +# GNU Build System (Autotools) +aclocal.m4 +autom4te.cache/ +autoscan.log +ChangeLog +compile +config.guess +config.h +config.h.in +config.log +config-ml.in +config.py +config.status +config.status.lineno +config.sub +configure +configure.scan +depcomp +.deps/ +INSTALL +install-sh +.libs/ +libtool +libtool.m4 +ltmain.sh +lt~obsolete.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +Makefile +Makefile.in +mdate-sh +missing +mkinstalldirs +*.pc +py-compile +stamp-h? +symlink-tree +texinfo.tex +ylwrap + +# Do not edit the following section +# Edit Compile Debug Document Distribute +*~ +*.[0-9] +*.[0-9]x +*.bak +*.bin +core +*.dll +*.exe +*-ISO*.bdf +*-JIS*.bdf +*-KOI8*.bdf +*.kld +*.ko +*.ko.cmd +*.lai +*.l[oa] +*.[oa] +*.obj +*.patch +*.so +*.pcf.gz +*.pdb +*.tar.bz2 +*.tar.gz +# +# Add & Override patterns for xkbcomp +# +# Edit the following section as needed +# For example, !report.pc overrides *.pc. See 'man gitignore' +# +xkbcomp +xkbparse.c diff --git a/xkbcomp/COPYING b/xkbcomp/COPYING index 867c4723c..fc22e80e8 100644 --- a/xkbcomp/COPYING +++ b/xkbcomp/COPYING @@ -1,90 +1,90 @@ -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.
-
-
-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.
-
-
- 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.
+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. + + +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. + + + 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. diff --git a/xkbcomp/action.c b/xkbcomp/action.c index fe022187c..3b82e647e 100644 --- a/xkbcomp/action.c +++ b/xkbcomp/action.c @@ -1,1468 +1,1468 @@ -/************************************************************
- 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 "vmod.h"
-#include "misc.h"
-#include "action.h"
-#include "misc.h"
-
-static Bool actionsInitialized;
-static ExprDef constTrue;
-static ExprDef constFalse;
-
-/***====================================================================***/
-
-static Bool
-stringToAction(char *str, unsigned *type_rtrn)
-{
- if (str == NULL)
- return False;
-
- if (uStrCaseCmp(str, "noaction") == 0)
- *type_rtrn = XkbSA_NoAction;
- else if (uStrCaseCmp(str, "setmods") == 0)
- *type_rtrn = XkbSA_SetMods;
- else if (uStrCaseCmp(str, "latchmods") == 0)
- *type_rtrn = XkbSA_LatchMods;
- else if (uStrCaseCmp(str, "lockmods") == 0)
- *type_rtrn = XkbSA_LockMods;
- else if (uStrCaseCmp(str, "setgroup") == 0)
- *type_rtrn = XkbSA_SetGroup;
- else if (uStrCaseCmp(str, "latchgroup") == 0)
- *type_rtrn = XkbSA_LatchGroup;
- else if (uStrCaseCmp(str, "lockgroup") == 0)
- *type_rtrn = XkbSA_LockGroup;
- else if (uStrCaseCmp(str, "moveptr") == 0)
- *type_rtrn = XkbSA_MovePtr;
- else if (uStrCaseCmp(str, "movepointer") == 0)
- *type_rtrn = XkbSA_MovePtr;
- else if (uStrCaseCmp(str, "ptrbtn") == 0)
- *type_rtrn = XkbSA_PtrBtn;
- else if (uStrCaseCmp(str, "pointerbutton") == 0)
- *type_rtrn = XkbSA_PtrBtn;
- else if (uStrCaseCmp(str, "lockptrbtn") == 0)
- *type_rtrn = XkbSA_LockPtrBtn;
- else if (uStrCaseCmp(str, "lockpointerbutton") == 0)
- *type_rtrn = XkbSA_LockPtrBtn;
- else if (uStrCaseCmp(str, "lockptrbutton") == 0)
- *type_rtrn = XkbSA_LockPtrBtn;
- else if (uStrCaseCmp(str, "lockpointerbtn") == 0)
- *type_rtrn = XkbSA_LockPtrBtn;
- else if (uStrCaseCmp(str, "setptrdflt") == 0)
- *type_rtrn = XkbSA_SetPtrDflt;
- else if (uStrCaseCmp(str, "setpointerdefault") == 0)
- *type_rtrn = XkbSA_SetPtrDflt;
- else if (uStrCaseCmp(str, "isolock") == 0)
- *type_rtrn = XkbSA_ISOLock;
- else if (uStrCaseCmp(str, "terminate") == 0)
- *type_rtrn = XkbSA_Terminate;
- else if (uStrCaseCmp(str, "terminateserver") == 0)
- *type_rtrn = XkbSA_Terminate;
- else if (uStrCaseCmp(str, "switchscreen") == 0)
- *type_rtrn = XkbSA_SwitchScreen;
- else if (uStrCaseCmp(str, "setcontrols") == 0)
- *type_rtrn = XkbSA_SetControls;
- else if (uStrCaseCmp(str, "lockcontrols") == 0)
- *type_rtrn = XkbSA_LockControls;
- else if (uStrCaseCmp(str, "actionmessage") == 0)
- *type_rtrn = XkbSA_ActionMessage;
- else if (uStrCaseCmp(str, "messageaction") == 0)
- *type_rtrn = XkbSA_ActionMessage;
- else if (uStrCaseCmp(str, "message") == 0)
- *type_rtrn = XkbSA_ActionMessage;
- else if (uStrCaseCmp(str, "redirect") == 0)
- *type_rtrn = XkbSA_RedirectKey;
- else if (uStrCaseCmp(str, "redirectkey") == 0)
- *type_rtrn = XkbSA_RedirectKey;
- else if (uStrCaseCmp(str, "devbtn") == 0)
- *type_rtrn = XkbSA_DeviceBtn;
- else if (uStrCaseCmp(str, "devicebtn") == 0)
- *type_rtrn = XkbSA_DeviceBtn;
- else if (uStrCaseCmp(str, "devbutton") == 0)
- *type_rtrn = XkbSA_DeviceBtn;
- else if (uStrCaseCmp(str, "devicebutton") == 0)
- *type_rtrn = XkbSA_DeviceBtn;
- else if (uStrCaseCmp(str, "lockdevbtn") == 0)
- *type_rtrn = XkbSA_DeviceBtn;
- else if (uStrCaseCmp(str, "lockdevicebtn") == 0)
- *type_rtrn = XkbSA_LockDeviceBtn;
- else if (uStrCaseCmp(str, "lockdevbutton") == 0)
- *type_rtrn = XkbSA_LockDeviceBtn;
- else if (uStrCaseCmp(str, "lockdevicebutton") == 0)
- *type_rtrn = XkbSA_LockDeviceBtn;
- else if (uStrCaseCmp(str, "devval") == 0)
- *type_rtrn = XkbSA_DeviceValuator;
- else if (uStrCaseCmp(str, "deviceval") == 0)
- *type_rtrn = XkbSA_DeviceValuator;
- else if (uStrCaseCmp(str, "devvaluator") == 0)
- *type_rtrn = XkbSA_DeviceValuator;
- else if (uStrCaseCmp(str, "devicevaluator") == 0)
- *type_rtrn = XkbSA_DeviceValuator;
- else if (uStrCaseCmp(str, "private") == 0)
- *type_rtrn = PrivateAction;
- else
- return False;
- return True;
-}
-
-static Bool
-stringToField(char *str, unsigned *field_rtrn)
-{
-
- if (str == NULL)
- return False;
-
- if (uStrCaseCmp(str, "clearlocks") == 0)
- *field_rtrn = F_ClearLocks;
- else if (uStrCaseCmp(str, "latchtolock") == 0)
- *field_rtrn = F_LatchToLock;
- else if (uStrCaseCmp(str, "genkeyevent") == 0)
- *field_rtrn = F_GenKeyEvent;
- else if (uStrCaseCmp(str, "generatekeyevent") == 0)
- *field_rtrn = F_GenKeyEvent;
- else if (uStrCaseCmp(str, "report") == 0)
- *field_rtrn = F_Report;
- else if (uStrCaseCmp(str, "default") == 0)
- *field_rtrn = F_Default;
- else if (uStrCaseCmp(str, "affect") == 0)
- *field_rtrn = F_Affect;
- else if (uStrCaseCmp(str, "increment") == 0)
- *field_rtrn = F_Increment;
- else if (uStrCaseCmp(str, "mods") == 0)
- *field_rtrn = F_Modifiers;
- else if (uStrCaseCmp(str, "modifiers") == 0)
- *field_rtrn = F_Modifiers;
- else if (uStrCaseCmp(str, "group") == 0)
- *field_rtrn = F_Group;
- else if (uStrCaseCmp(str, "x") == 0)
- *field_rtrn = F_X;
- else if (uStrCaseCmp(str, "y") == 0)
- *field_rtrn = F_Y;
- else if (uStrCaseCmp(str, "accel") == 0)
- *field_rtrn = F_Accel;
- else if (uStrCaseCmp(str, "accelerate") == 0)
- *field_rtrn = F_Accel;
- else if (uStrCaseCmp(str, "repeat") == 0)
- *field_rtrn = F_Accel;
- else if (uStrCaseCmp(str, "button") == 0)
- *field_rtrn = F_Button;
- else if (uStrCaseCmp(str, "value") == 0)
- *field_rtrn = F_Value;
- else if (uStrCaseCmp(str, "controls") == 0)
- *field_rtrn = F_Controls;
- else if (uStrCaseCmp(str, "ctrls") == 0)
- *field_rtrn = F_Controls;
- else if (uStrCaseCmp(str, "type") == 0)
- *field_rtrn = F_Type;
- else if (uStrCaseCmp(str, "count") == 0)
- *field_rtrn = F_Count;
- else if (uStrCaseCmp(str, "screen") == 0)
- *field_rtrn = F_Screen;
- else if (uStrCaseCmp(str, "same") == 0)
- *field_rtrn = F_Same;
- else if (uStrCaseCmp(str, "sameserver") == 0)
- *field_rtrn = F_Same;
- else if (uStrCaseCmp(str, "data") == 0)
- *field_rtrn = F_Data;
- else if (uStrCaseCmp(str, "device") == 0)
- *field_rtrn = F_Device;
- else if (uStrCaseCmp(str, "dev") == 0)
- *field_rtrn = F_Device;
- else if (uStrCaseCmp(str, "key") == 0)
- *field_rtrn = F_Keycode;
- else if (uStrCaseCmp(str, "keycode") == 0)
- *field_rtrn = F_Keycode;
- else if (uStrCaseCmp(str, "kc") == 0)
- *field_rtrn = F_Keycode;
- else if (uStrCaseCmp(str, "clearmods") == 0)
- *field_rtrn = F_ModsToClear;
- else if (uStrCaseCmp(str, "clearmodifiers") == 0)
- *field_rtrn = F_ModsToClear;
- else
- return False;
- return True;
-}
-
-static char *
-fieldText(unsigned field)
-{
- static char buf[32];
-
- switch (field)
- {
- case F_ClearLocks:
- strcpy(buf, "clearLocks");
- break;
- case F_LatchToLock:
- strcpy(buf, "latchToLock");
- break;
- case F_GenKeyEvent:
- strcpy(buf, "genKeyEvent");
- break;
- case F_Report:
- strcpy(buf, "report");
- break;
- case F_Default:
- strcpy(buf, "default");
- break;
- case F_Affect:
- strcpy(buf, "affect");
- break;
- case F_Increment:
- strcpy(buf, "increment");
- break;
- case F_Modifiers:
- strcpy(buf, "modifiers");
- break;
- case F_Group:
- strcpy(buf, "group");
- break;
- case F_X:
- strcpy(buf, "x");
- break;
- case F_Y:
- strcpy(buf, "y");
- break;
- case F_Accel:
- strcpy(buf, "accel");
- break;
- case F_Button:
- strcpy(buf, "button");
- break;
- case F_Value:
- strcpy(buf, "value");
- break;
- case F_Controls:
- strcpy(buf, "controls");
- break;
- case F_Type:
- strcpy(buf, "type");
- break;
- case F_Count:
- strcpy(buf, "count");
- break;
- case F_Screen:
- strcpy(buf, "screen");
- break;
- case F_Same:
- strcpy(buf, "sameServer");
- break;
- case F_Data:
- strcpy(buf, "data");
- break;
- case F_Device:
- strcpy(buf, "device");
- break;
- case F_Keycode:
- strcpy(buf, "keycode");
- break;
- case F_ModsToClear:
- strcpy(buf, "clearmods");
- break;
- default:
- strcpy(buf, "unknown");
- break;
- }
- return buf;
-}
-
-/***====================================================================***/
-
-static Bool
-ReportMismatch(unsigned action, unsigned field, const char *type)
-{
- ERROR2("Value of %s field must be of type %s\n", fieldText(field), type);
- ACTION1("Action %s definition ignored\n",
- XkbActionTypeText(action, XkbMessage));
- return False;
-}
-
-static Bool
-ReportIllegal(unsigned action, unsigned field)
-{
- ERROR2("Field %s is not defined for an action of type %s\n",
- fieldText(field), XkbActionTypeText(action, XkbMessage));
- ACTION("Action definition ignored\n");
- return False;
-}
-
-static Bool
-ReportActionNotArray(unsigned action, unsigned field)
-{
- ERROR2("The %s field in the %s action is not an array\n",
- fieldText(field), XkbActionTypeText(action, XkbMessage));
- ACTION("Action definition ignored\n");
- return False;
-}
-
-static Bool
-ReportNotFound(unsigned action, unsigned field, const char *what, char *bad)
-{
- ERROR2("%s named %s not found\n", what, bad);
- ACTION2("Ignoring the %s field of an %s action\n", fieldText(field),
- XkbActionTypeText(action, XkbMessage));
- return False;
-}
-
-static Bool
-HandleNoAction(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-CheckLatchLockFlags(unsigned action,
- unsigned field, ExprDef * value, unsigned *flags_inout)
-{
- unsigned tmp;
- ExprResult result;
-
- if (field == F_ClearLocks)
- tmp = XkbSA_ClearLocks;
- else if (field == F_LatchToLock)
- tmp = XkbSA_LatchToLock;
- else
- return False; /* WSGO! */
- if (!ExprResolveBoolean(value, &result, NULL, NULL))
- return ReportMismatch(action, field, "boolean");
- if (result.uval)
- *flags_inout |= tmp;
- else
- *flags_inout &= ~tmp;
- return True;
-}
-
-static Bool
-CheckModifierField(XkbDescPtr xkb,
- unsigned action,
- ExprDef * value,
- unsigned *flags_inout, unsigned *mods_rtrn)
-{
- ExprResult rtrn;
-
- if (value->op == ExprIdent)
- {
- register char *valStr;
- valStr = XkbAtomGetString(NULL, value->value.str);
- if (valStr && ((uStrCaseCmp(valStr, "usemodmapmods") == 0) ||
- (uStrCaseCmp(valStr, "modmapmods") == 0)))
- {
-
- *mods_rtrn = 0;
- *flags_inout |= XkbSA_UseModMapMods;
- return True;
- }
- }
- if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
- return ReportMismatch(action, F_Modifiers, "modifier mask");
- *mods_rtrn = rtrn.uval;
- *flags_inout &= ~XkbSA_UseModMapMods;
- return True;
-}
-
-static Bool
-HandleSetLatchMods(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- XkbModAction *act;
- unsigned rtrn;
- unsigned t1, t2;
-
- act = (XkbModAction *) action;
- if (array_ndx != NULL)
- {
- switch (field)
- {
- case F_ClearLocks:
- case F_LatchToLock:
- case F_Modifiers:
- return ReportActionNotArray(action->type, field);
- }
- }
- switch (field)
- {
- case F_ClearLocks:
- case F_LatchToLock:
- rtrn = act->flags;
- if (CheckLatchLockFlags(action->type, field, value, &rtrn))
- {
- act->flags = rtrn;
- return True;
- }
- return False;
- case F_Modifiers:
- t1 = act->flags;
- if (CheckModifierField(xkb, action->type, value, &t1, &t2))
- {
- act->flags = t1;
- act->real_mods = act->mask = (t2 & 0xff);
- t2 = (t2 >> 8) & 0xffff;
- XkbSetModActionVMods(act, t2);
- return True;
- }
- return False;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleLockMods(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- XkbModAction *act;
- unsigned t1, t2;
-
- act = (XkbModAction *) action;
- if ((array_ndx != NULL) && (field == F_Modifiers))
- return ReportActionNotArray(action->type, field);
- switch (field)
- {
- case F_Modifiers:
- t1 = act->flags;
- if (CheckModifierField(xkb, action->type, value, &t1, &t2))
- {
- act->flags = t1;
- act->real_mods = act->mask = (t2 & 0xff);
- t2 = (t2 >> 8) & 0xffff;
- XkbSetModActionVMods(act, t2);
- return True;
- }
- return False;
- }
- return ReportIllegal(action->type, field);
-}
-
-static LookupEntry groupNames[] = {
- {"group1", 1},
- {"group2", 2},
- {"group3", 3},
- {"group4", 4},
- {"group5", 5},
- {"group6", 6},
- {"group7", 7},
- {"group8", 8},
- {NULL, 0},
-};
-
-static Bool
-CheckGroupField(unsigned action,
- ExprDef * value, unsigned *flags_inout, int *grp_rtrn)
-{
- ExprDef *spec;
- ExprResult rtrn;
-
- if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
- {
- *flags_inout &= ~XkbSA_GroupAbsolute;
- spec = value->value.child;
- }
- else
- {
- *flags_inout |= XkbSA_GroupAbsolute;
- spec = value;
- }
-
- if (!ExprResolveInteger(spec, &rtrn, SimpleLookup, (XPointer) groupNames))
- return ReportMismatch(action, F_Group, "integer (range 1..8)");
- if ((rtrn.ival < 1) || (rtrn.ival > XkbNumKbdGroups))
- {
- ERROR2("Illegal group %d (must be in the range 1..%d)\n", rtrn.ival,
- XkbNumKbdGroups);
- ACTION1("Action %s definition ignored\n",
- XkbActionTypeText(action, XkbMessage));
- return False;
- }
- if (value->op == OpNegate)
- *grp_rtrn = -rtrn.ival;
- else if (value->op == OpUnaryPlus)
- *grp_rtrn = rtrn.ival;
- else
- *grp_rtrn = rtrn.ival - 1;
- return True;
-}
-
-static Bool
-HandleSetLatchGroup(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- XkbGroupAction *act;
- unsigned rtrn;
- unsigned t1;
- int t2;
-
- act = (XkbGroupAction *) action;
- if (array_ndx != NULL)
- {
- switch (field)
- {
- case F_ClearLocks:
- case F_LatchToLock:
- case F_Group:
- return ReportActionNotArray(action->type, field);
- }
- }
- switch (field)
- {
- case F_ClearLocks:
- case F_LatchToLock:
- rtrn = act->flags;
- if (CheckLatchLockFlags(action->type, field, value, &rtrn))
- {
- act->flags = rtrn;
- return True;
- }
- return False;
- case F_Group:
- t1 = act->flags;
- if (CheckGroupField(action->type, value, &t1, &t2))
- {
- act->flags = t1;
- XkbSASetGroup(act, t2);
- return True;
- }
- return False;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleLockGroup(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- XkbGroupAction *act;
- unsigned t1;
- int t2;
-
- act = (XkbGroupAction *) action;
- if ((array_ndx != NULL) && (field == F_Group))
- return ReportActionNotArray(action->type, field);
- if (field == F_Group)
- {
- t1 = act->flags;
- if (CheckGroupField(action->type, value, &t1, &t2))
- {
- act->flags = t1;
- XkbSASetGroup(act, t2);
- return True;
- }
- return False;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleMovePtr(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbPtrAction *act;
- Bool absolute;
-
- act = (XkbPtrAction *) action;
- if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y)))
- return ReportActionNotArray(action->type, field);
-
- if ((field == F_X) || (field == F_Y))
- {
- if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
- absolute = False;
- else
- absolute = True;
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "integer");
- if (field == F_X)
- {
- if (absolute)
- act->flags |= XkbSA_MoveAbsoluteX;
- XkbSetPtrActionX(act, rtrn.ival);
- }
- else
- {
- if (absolute)
- act->flags |= XkbSA_MoveAbsoluteY;
- XkbSetPtrActionY(act, rtrn.ival);
- }
- return True;
- }
- else if (field == F_Accel)
- {
- if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "boolean");
- if (rtrn.uval)
- act->flags &= ~XkbSA_NoAcceleration;
- else
- act->flags |= XkbSA_NoAcceleration;
- }
- return ReportIllegal(action->type, field);
-}
-
-static LookupEntry btnNames[] = {
- {"button1", 1},
- {"button2", 2},
- {"button3", 3},
- {"button4", 4},
- {"button5", 5},
- {"default", 0},
- {NULL, 0}
-};
-
-static LookupEntry lockWhich[] = {
- {"both", 0},
- {"lock", XkbSA_LockNoUnlock},
- {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)},
- {"unlock", XkbSA_LockNoLock},
- {NULL, 0}
-};
-
-static Bool
-HandlePtrBtn(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbPtrBtnAction *act;
-
- act = (XkbPtrBtnAction *) action;
- if (field == F_Button)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveInteger
- (value, &rtrn, SimpleLookup, (XPointer) btnNames))
- return ReportMismatch(action->type, field,
- "integer (range 1..5)");
- if ((rtrn.ival < 0) || (rtrn.ival > 5))
- {
- ERROR("Button must specify default or be in the range 1..5\n");
- ACTION1("Illegal button value %d ignored\n", rtrn.ival);
- return False;
- }
- act->button = rtrn.ival;
- return True;
- }
- else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect))
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveEnum(value, &rtrn, lockWhich))
- return ReportMismatch(action->type, field, "lock or unlock");
- act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
- act->flags |= rtrn.ival;
- return True;
- }
- else if (field == F_Count)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveInteger
- (value, &rtrn, SimpleLookup, (XPointer) btnNames))
- return ReportMismatch(action->type, field, "integer");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("The count field must have a value in the range 0..255\n");
- ACTION1("Illegal count %d ignored\n", rtrn.ival);
- return False;
- }
- act->count = rtrn.ival;
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static LookupEntry ptrDflts[] = {
- {"dfltbtn", XkbSA_AffectDfltBtn},
- {"defaultbutton", XkbSA_AffectDfltBtn},
- {"button", XkbSA_AffectDfltBtn},
- {NULL, 0}
-};
-
-static Bool
-HandleSetPtrDflt(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbPtrDfltAction *act;
-
- act = (XkbPtrDfltAction *) action;
- if (field == F_Affect)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveEnum(value, &rtrn, ptrDflts))
- return ReportMismatch(action->type, field, "pointer component");
- act->affect = rtrn.uval;
- return True;
- }
- else if ((field == F_Button) || (field == F_Value))
- {
- ExprDef *btn;
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
- {
- act->flags &= ~XkbSA_DfltBtnAbsolute;
- btn = value->value.child;
- }
- else
- {
- act->flags |= XkbSA_DfltBtnAbsolute;
- btn = value;
- }
-
- if (!ExprResolveInteger
- (btn, &rtrn, SimpleLookup, (XPointer) btnNames))
- return ReportMismatch(action->type, field,
- "integer (range 1..5)");
- if ((rtrn.ival < 0) || (rtrn.ival > 5))
- {
- ERROR("New default button value must be in the range 1..5\n");
- ACTION1("Illegal default button value %d ignored\n", rtrn.ival);
- return False;
- }
- if (rtrn.ival == 0)
- {
- ERROR("Cannot set default pointer button to \"default\"\n");
- ACTION("Illegal default button setting ignored\n");
- return False;
- }
- if (value->op == OpNegate)
- XkbSASetPtrDfltValue(act, -rtrn.ival);
- else
- XkbSASetPtrDfltValue(act, rtrn.ival);
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static LookupEntry isoNames[] = {
- {"mods", XkbSA_ISONoAffectMods},
- {"modifiers", XkbSA_ISONoAffectMods},
- {"group", XkbSA_ISONoAffectGroup},
- {"groups", XkbSA_ISONoAffectGroup},
- {"ptr", XkbSA_ISONoAffectPtr},
- {"pointer", XkbSA_ISONoAffectPtr},
- {"ctrls", XkbSA_ISONoAffectCtrls},
- {"controls", XkbSA_ISONoAffectCtrls},
- {"all", ~((unsigned) 0)},
- {"none", 0},
- {NULL, 0},
-};
-
-static Bool
-HandleISOLock(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbISOAction *act;
- unsigned flags, mods;
- int group;
-
- act = (XkbISOAction *) action;
- switch (field)
- {
- case F_Modifiers:
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- flags = act->flags;
- if (CheckModifierField(xkb, action->type, value, &flags, &mods))
- {
- act->flags = flags & (~XkbSA_ISODfltIsGroup);
- act->real_mods = mods & 0xff;
- mods = (mods >> 8) & 0xff;
- XkbSetModActionVMods(act, mods);
- return True;
- }
- return False;
- case F_Group:
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- flags = act->flags;
- if (CheckGroupField(action->type, value, &flags, &group))
- {
- act->flags = flags | XkbSA_ISODfltIsGroup;
- XkbSASetGroup(act, group);
- return True;
- }
- return False;
- case F_Affect:
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) isoNames))
- return ReportMismatch(action->type, field, "keyboard component");
- act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask;
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleSwitchScreen(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbSwitchScreenAction *act;
-
- act = (XkbSwitchScreenAction *) action;
- if (field == F_Screen)
- {
- ExprDef *scrn;
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if ((value->op == OpNegate) || (value->op == OpUnaryPlus))
- {
- act->flags &= ~XkbSA_SwitchAbsolute;
- scrn = value->value.child;
- }
- else
- {
- act->flags |= XkbSA_SwitchAbsolute;
- scrn = value;
- }
-
- if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "integer (0..255)");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("Screen index must be in the range 1..255\n");
- ACTION1("Illegal screen value %d ignored\n", rtrn.ival);
- return False;
- }
- if (value->op == OpNegate)
- XkbSASetScreen(act, -rtrn.ival);
- else
- XkbSASetScreen(act, rtrn.ival);
- return True;
- }
- else if (field == F_Same)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "boolean");
- if (rtrn.uval)
- act->flags &= ~XkbSA_SwitchApplication;
- else
- act->flags |= XkbSA_SwitchApplication;
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-LookupEntry ctrlNames[] = {
- {"repeatkeys", XkbRepeatKeysMask}
- ,
- {"repeat", XkbRepeatKeysMask}
- ,
- {"autorepeat", XkbRepeatKeysMask}
- ,
- {"slowkeys", XkbSlowKeysMask}
- ,
- {"bouncekeys", XkbBounceKeysMask}
- ,
- {"stickykeys", XkbStickyKeysMask}
- ,
- {"mousekeys", XkbMouseKeysMask}
- ,
- {"mousekeysaccel", XkbMouseKeysAccelMask}
- ,
- {"accessxkeys", XkbAccessXKeysMask}
- ,
- {"accessxtimeout", XkbAccessXTimeoutMask}
- ,
- {"accessxfeedback", XkbAccessXFeedbackMask}
- ,
- {"audiblebell", XkbAudibleBellMask}
- ,
- {"overlay1", XkbOverlay1Mask}
- ,
- {"overlay2", XkbOverlay2Mask}
- ,
- {"ignoregrouplock", XkbIgnoreGroupLockMask}
- ,
- {"all", XkbAllBooleanCtrlsMask}
- ,
- {"none", 0}
- ,
- {NULL, 0}
-};
-
-static Bool
-HandleSetLockControls(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbCtrlsAction *act;
-
- act = (XkbCtrlsAction *) action;
- if (field == F_Controls)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveMask
- (value, &rtrn, SimpleLookup, (XPointer) ctrlNames))
- return ReportMismatch(action->type, field, "controls mask");
- XkbActionSetCtrls(act, rtrn.uval);
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static LookupEntry evNames[] = {
- {"press", XkbSA_MessageOnPress},
- {"keypress", XkbSA_MessageOnPress},
- {"release", XkbSA_MessageOnRelease},
- {"keyrelease", XkbSA_MessageOnRelease},
- {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease},
- {"none", 0},
- {NULL, 0}
-};
-
-static Bool
-HandleActionMessage(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbMessageAction *act;
-
- act = (XkbMessageAction *) action;
- switch (field)
- {
- case F_Report:
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) evNames))
- return ReportMismatch(action->type, field, "key event mask");
- act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
- act->flags =
- rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease);
- return True;
- case F_GenKeyEvent:
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "boolean");
- if (rtrn.uval)
- act->flags |= XkbSA_MessageGenKeyEvent;
- else
- act->flags &= ~XkbSA_MessageGenKeyEvent;
- return True;
- case F_Data:
- if (array_ndx == NULL)
- {
- if (!ExprResolveString(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "string");
- else
- {
- int len = strlen(rtrn.str);
- if ((len < 1) || (len > 6))
- {
- WARN("An action message can hold only 6 bytes\n");
- ACTION1("Extra %d bytes ignored\n", len - 6);
- }
- strncpy((char *) act->message, rtrn.str, 6);
- }
- return True;
- }
- else
- {
- unsigned ndx;
- if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
- {
- ERROR("Array subscript must be integer\n");
- ACTION("Illegal subscript ignored\n");
- return False;
- }
- ndx = rtrn.uval;
- if (ndx > 5)
- {
- ERROR("An action message is at most 6 bytes long\n");
- ACTION1("Attempt to use data[%d] ignored\n", ndx);
- return False;
- }
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "integer");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("Message data must be in the range 0..255\n");
- ACTION1("Illegal datum %d ignored\n", rtrn.ival);
- return False;
- }
- act->message[ndx] = rtrn.uval;
- }
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleRedirectKey(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbRedirectKeyAction *act;
- unsigned t1, t2, vmods, vmask;
- unsigned long tmp;
-
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
-
- act = (XkbRedirectKeyAction *) action;
- switch (field)
- {
- case F_Keycode:
- if (!ExprResolveKeyName(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "key name");
- tmp = KeyNameToLong(rtrn.keyName.name);
- if (!FindNamedKey(xkb, tmp, &t1, True, CreateKeyNames(xkb), 0))
- {
- return ReportNotFound(action->type, field, "Key",
- XkbKeyNameText(rtrn.keyName.name,
- XkbMessage));
- }
- act->new_key = t1;
- return True;
- case F_ModsToClear:
- case F_Modifiers:
- t1 = 0;
- if (CheckModifierField(xkb, action->type, value, &t1, &t2))
- {
- act->mods_mask |= (t2 & 0xff);
- if (field == F_Modifiers)
- act->mods |= (t2 & 0xff);
- else
- act->mods &= ~(t2 & 0xff);
-
- t2 = (t2 >> 8) & 0xffff;
- vmods = XkbSARedirectVMods(act);
- vmask = XkbSARedirectVModsMask(act);
- vmask |= t2;
- if (field == F_Modifiers)
- vmods |= t2;
- else
- vmods &= ~t2;
- XkbSARedirectSetVMods(act, vmods);
- XkbSARedirectSetVModsMask(act, vmask);
- return True;
- }
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleDeviceBtn(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbDeviceBtnAction *act;
-
- act = (XkbDeviceBtnAction *) action;
- if (field == F_Button)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field,
- "integer (range 1..255)");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("Button must specify default or be in the range 1..255\n");
- ACTION1("Illegal button value %d ignored\n", rtrn.ival);
- return False;
- }
- act->button = rtrn.ival;
- return True;
- }
- else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect))
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveEnum(value, &rtrn, lockWhich))
- return ReportMismatch(action->type, field, "lock or unlock");
- act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock);
- act->flags |= rtrn.ival;
- return True;
- }
- else if (field == F_Count)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveInteger
- (value, &rtrn, SimpleLookup, (XPointer) btnNames))
- return ReportMismatch(action->type, field, "integer");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("The count field must have a value in the range 0..255\n");
- ACTION1("Illegal count %d ignored\n", rtrn.ival);
- return False;
- }
- act->count = rtrn.ival;
- return True;
- }
- else if (field == F_Device)
- {
- if (array_ndx != NULL)
- return ReportActionNotArray(action->type, field);
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field,
- "integer (range 1..255)");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("Device must specify default or be in the range 1..255\n");
- ACTION1("Illegal device value %d ignored\n", rtrn.ival);
- return False;
- }
- act->device = rtrn.ival;
- return True;
- }
- return ReportIllegal(action->type, field);
-}
-
-static Bool
-HandleDeviceValuator(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
-#if 0
- ExprResult rtrn;
- XkbDeviceValuatorAction *act;
-
- act = (XkbDeviceValuatorAction *) action;
- /* XXX - Not yet implemented */
-#endif
- return False;
-}
-
-static Bool
-HandlePrivate(XkbDescPtr xkb,
- XkbAnyAction * action,
- unsigned field, ExprDef * array_ndx, ExprDef * value)
-{
- ExprResult rtrn;
-
- switch (field)
- {
- case F_Type:
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(PrivateAction, field, "integer");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("Private action type must be in the range 0..255\n");
- ACTION1("Illegal type %d ignored\n", rtrn.ival);
- return False;
- }
- action->type = rtrn.uval;
- return True;
- case F_Data:
- if (array_ndx == NULL)
- {
- if (!ExprResolveString(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "string");
- else
- {
- int len = strlen(rtrn.str);
- if ((len < 1) || (len > 7))
- {
- WARN("A private action has 7 data bytes\n");
- ACTION1("Extra %d bytes ignored\n", len - 6);
- return False;
- }
- strncpy((char *) action->data, rtrn.str, 7);
- }
- return True;
- }
- else
- {
- unsigned ndx;
- if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL))
- {
- ERROR("Array subscript must be integer\n");
- ACTION("Illegal subscript ignored\n");
- return False;
- }
- ndx = rtrn.uval;
- if (ndx > 6)
- {
- ERROR("The data for a private action is 7 bytes long\n");
- ACTION1("Attempt to use data[%d] ignored\n", ndx);
- return False;
- }
- if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
- return ReportMismatch(action->type, field, "integer");
- if ((rtrn.ival < 0) || (rtrn.ival > 255))
- {
- ERROR("All data for a private action must be 0..255\n");
- ACTION1("Illegal datum %d ignored\n", rtrn.ival);
- return False;
- }
- action->data[ndx] = rtrn.uval;
- return True;
- }
- }
- return ReportIllegal(PrivateAction, field);
-}
-
-typedef Bool(*actionHandler) (XkbDescPtr /* xkb */ ,
- XkbAnyAction * /* action */ ,
- unsigned /* field */ ,
- ExprDef * /* array_ndx */ ,
- ExprDef * /* value */
- );
-
-static actionHandler handleAction[XkbSA_NumActions + 1] = {
- HandleNoAction /* NoAction */ ,
- HandleSetLatchMods /* SetMods */ ,
- HandleSetLatchMods /* LatchMods */ ,
- HandleLockMods /* LockMods */ ,
- HandleSetLatchGroup /* SetGroup */ ,
- HandleSetLatchGroup /* LatchGroup */ ,
- HandleLockGroup /* LockGroup */ ,
- HandleMovePtr /* MovePtr */ ,
- HandlePtrBtn /* PtrBtn */ ,
- HandlePtrBtn /* LockPtrBtn */ ,
- HandleSetPtrDflt /* SetPtrDflt */ ,
- HandleISOLock /* ISOLock */ ,
- HandleNoAction /* Terminate */ ,
- HandleSwitchScreen /* SwitchScreen */ ,
- HandleSetLockControls /* SetControls */ ,
- HandleSetLockControls /* LockControls */ ,
- HandleActionMessage /* ActionMessage */ ,
- HandleRedirectKey /* RedirectKey */ ,
- HandleDeviceBtn /* DeviceBtn */ ,
- HandleDeviceBtn /* LockDeviceBtn */ ,
- HandleDeviceValuator /* DeviceValuatr */ ,
- HandlePrivate /* Private */
-};
-
-/***====================================================================***/
-
-static void
-ApplyActionFactoryDefaults(XkbAction * action)
-{
- if (action->type == XkbSA_SetPtrDflt)
- { /* increment default button */
- action->dflt.affect = XkbSA_AffectDfltBtn;
- action->dflt.flags = 0;
- XkbSASetPtrDfltValue(&action->dflt, 1);
- }
- else if (action->type == XkbSA_ISOLock)
- {
- action->iso.real_mods = LockMask;
- }
- return;
-}
-
-
-int
-HandleActionDef(ExprDef * def,
- XkbDescPtr xkb,
- XkbAnyAction * action, unsigned mergeMode, ActionInfo * info)
-{
- ExprDef *arg;
- register char *str;
- unsigned tmp, hndlrType;
-
- if (!actionsInitialized)
- ActionsInit();
-
- if (def->op != ExprActionDecl)
- {
- ERROR1("Expected an action definition, found %s\n",
- exprOpText(def->op));
- return False;
- }
- str = XkbAtomGetString(NULL, def->value.action.name);
- if (!str)
- {
- WSGO("Missing name in action definition!!\n");
- return False;
- }
- if (!stringToAction(str, &tmp))
- {
- ERROR1("Unknown action %s\n", str);
- return False;
- }
- action->type = hndlrType = tmp;
- if (action->type != XkbSA_NoAction)
- {
- ApplyActionFactoryDefaults((XkbAction *) action);
- while (info)
- {
- if ((info->action == XkbSA_NoAction)
- || (info->action == hndlrType))
- {
- if (!(*handleAction[hndlrType]) (xkb, action,
- info->field,
- info->array_ndx,
- info->value))
- {
- return False;
- }
- }
- info = info->next;
- }
- }
- for (arg = def->value.action.args; arg != NULL;
- arg = (ExprDef *) arg->common.next)
- {
- ExprDef *field, *value, *arrayRtrn;
- ExprResult elemRtrn, fieldRtrn;
- unsigned fieldNdx;
-
- if (arg->op == OpAssign)
- {
- field = arg->value.binary.left;
- value = arg->value.binary.right;
- }
- else
- {
- if ((arg->op == OpNot) || (arg->op == OpInvert))
- {
- field = arg->value.child;
- value = &constFalse;
- }
- else
- {
- field = arg;
- value = &constTrue;
- }
- }
- if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn))
- return False; /* internal error -- already reported */
-
- if (elemRtrn.str != NULL)
- {
- ERROR("Cannot change defaults in an action definition\n");
- ACTION2("Ignoring attempt to change %s.%s\n", elemRtrn.str,
- fieldRtrn.str);
- return False;
- }
- if (!stringToField(fieldRtrn.str, &fieldNdx))
- {
- ERROR1("Unknown field name %s\n", uStringText(fieldRtrn.str));
- return False;
- }
- if (!(*handleAction[hndlrType])
- (xkb, action, fieldNdx, arrayRtrn, value))
- {
- return False;
- }
- }
- return True;
-}
-
-/***====================================================================***/
-
-int
-SetActionField(XkbDescPtr xkb,
- char *elem,
- char *field,
- ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn)
-{
- ActionInfo *new, *old;
-
- if (!actionsInitialized)
- ActionsInit();
-
- new = uTypedAlloc(ActionInfo);
- if (new == NULL)
- {
- WSGO("Couldn't allocate space for action default\n");
- return False;
- }
- if (uStrCaseCmp(elem, "action") == 0)
- new->action = XkbSA_NoAction;
- else
- {
- if (!stringToAction(elem, &new->action))
- return False;
- if (new->action == XkbSA_NoAction)
- {
- ERROR1("\"%s\" is not a valid field in a NoAction action\n",
- field);
- return False;
- }
- }
- if (!stringToField(field, &new->field))
- {
- ERROR1("\"%s\" is not a legal field name\n", field);
- return False;
- }
- new->array_ndx = array_ndx;
- new->value = value;
- new->next = NULL;
- old = *info_rtrn;
- while ((old) && (old->next))
- old = old->next;
- if (old == NULL)
- *info_rtrn = new;
- else
- old->next = new;
- return True;
-}
-
-/***====================================================================***/
-
-void
-ActionsInit(void)
-{
- if (!actionsInitialized)
- {
- bzero((char *) &constTrue, sizeof(constTrue));
- bzero((char *) &constFalse, sizeof(constFalse));
- constTrue.common.stmtType = StmtExpr;
- constTrue.common.next = NULL;
- constTrue.op = ExprIdent;
- constTrue.type = TypeBoolean;
- constTrue.value.str = XkbInternAtom(NULL, "true", False);
- constFalse.common.stmtType = StmtExpr;
- constFalse.common.next = NULL;
- constFalse.op = ExprIdent;
- constFalse.type = TypeBoolean;
- constFalse.value.str = XkbInternAtom(NULL, "false", False);
- actionsInitialized = 1;
- }
- return;
-}
+/************************************************************ + 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 "vmod.h" +#include "misc.h" +#include "action.h" +#include "misc.h" + +static Bool actionsInitialized; +static ExprDef constTrue; +static ExprDef constFalse; + +/***====================================================================***/ + +static Bool +stringToAction(char *str, unsigned *type_rtrn) +{ + if (str == NULL) + return False; + + if (uStrCaseCmp(str, "noaction") == 0) + *type_rtrn = XkbSA_NoAction; + else if (uStrCaseCmp(str, "setmods") == 0) + *type_rtrn = XkbSA_SetMods; + else if (uStrCaseCmp(str, "latchmods") == 0) + *type_rtrn = XkbSA_LatchMods; + else if (uStrCaseCmp(str, "lockmods") == 0) + *type_rtrn = XkbSA_LockMods; + else if (uStrCaseCmp(str, "setgroup") == 0) + *type_rtrn = XkbSA_SetGroup; + else if (uStrCaseCmp(str, "latchgroup") == 0) + *type_rtrn = XkbSA_LatchGroup; + else if (uStrCaseCmp(str, "lockgroup") == 0) + *type_rtrn = XkbSA_LockGroup; + else if (uStrCaseCmp(str, "moveptr") == 0) + *type_rtrn = XkbSA_MovePtr; + else if (uStrCaseCmp(str, "movepointer") == 0) + *type_rtrn = XkbSA_MovePtr; + else if (uStrCaseCmp(str, "ptrbtn") == 0) + *type_rtrn = XkbSA_PtrBtn; + else if (uStrCaseCmp(str, "pointerbutton") == 0) + *type_rtrn = XkbSA_PtrBtn; + else if (uStrCaseCmp(str, "lockptrbtn") == 0) + *type_rtrn = XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str, "lockpointerbutton") == 0) + *type_rtrn = XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str, "lockptrbutton") == 0) + *type_rtrn = XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str, "lockpointerbtn") == 0) + *type_rtrn = XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str, "setptrdflt") == 0) + *type_rtrn = XkbSA_SetPtrDflt; + else if (uStrCaseCmp(str, "setpointerdefault") == 0) + *type_rtrn = XkbSA_SetPtrDflt; + else if (uStrCaseCmp(str, "isolock") == 0) + *type_rtrn = XkbSA_ISOLock; + else if (uStrCaseCmp(str, "terminate") == 0) + *type_rtrn = XkbSA_Terminate; + else if (uStrCaseCmp(str, "terminateserver") == 0) + *type_rtrn = XkbSA_Terminate; + else if (uStrCaseCmp(str, "switchscreen") == 0) + *type_rtrn = XkbSA_SwitchScreen; + else if (uStrCaseCmp(str, "setcontrols") == 0) + *type_rtrn = XkbSA_SetControls; + else if (uStrCaseCmp(str, "lockcontrols") == 0) + *type_rtrn = XkbSA_LockControls; + else if (uStrCaseCmp(str, "actionmessage") == 0) + *type_rtrn = XkbSA_ActionMessage; + else if (uStrCaseCmp(str, "messageaction") == 0) + *type_rtrn = XkbSA_ActionMessage; + else if (uStrCaseCmp(str, "message") == 0) + *type_rtrn = XkbSA_ActionMessage; + else if (uStrCaseCmp(str, "redirect") == 0) + *type_rtrn = XkbSA_RedirectKey; + else if (uStrCaseCmp(str, "redirectkey") == 0) + *type_rtrn = XkbSA_RedirectKey; + else if (uStrCaseCmp(str, "devbtn") == 0) + *type_rtrn = XkbSA_DeviceBtn; + else if (uStrCaseCmp(str, "devicebtn") == 0) + *type_rtrn = XkbSA_DeviceBtn; + else if (uStrCaseCmp(str, "devbutton") == 0) + *type_rtrn = XkbSA_DeviceBtn; + else if (uStrCaseCmp(str, "devicebutton") == 0) + *type_rtrn = XkbSA_DeviceBtn; + else if (uStrCaseCmp(str, "lockdevbtn") == 0) + *type_rtrn = XkbSA_DeviceBtn; + else if (uStrCaseCmp(str, "lockdevicebtn") == 0) + *type_rtrn = XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str, "lockdevbutton") == 0) + *type_rtrn = XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str, "lockdevicebutton") == 0) + *type_rtrn = XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str, "devval") == 0) + *type_rtrn = XkbSA_DeviceValuator; + else if (uStrCaseCmp(str, "deviceval") == 0) + *type_rtrn = XkbSA_DeviceValuator; + else if (uStrCaseCmp(str, "devvaluator") == 0) + *type_rtrn = XkbSA_DeviceValuator; + else if (uStrCaseCmp(str, "devicevaluator") == 0) + *type_rtrn = XkbSA_DeviceValuator; + else if (uStrCaseCmp(str, "private") == 0) + *type_rtrn = PrivateAction; + else + return False; + return True; +} + +static Bool +stringToField(char *str, unsigned *field_rtrn) +{ + + if (str == NULL) + return False; + + if (uStrCaseCmp(str, "clearlocks") == 0) + *field_rtrn = F_ClearLocks; + else if (uStrCaseCmp(str, "latchtolock") == 0) + *field_rtrn = F_LatchToLock; + else if (uStrCaseCmp(str, "genkeyevent") == 0) + *field_rtrn = F_GenKeyEvent; + else if (uStrCaseCmp(str, "generatekeyevent") == 0) + *field_rtrn = F_GenKeyEvent; + else if (uStrCaseCmp(str, "report") == 0) + *field_rtrn = F_Report; + else if (uStrCaseCmp(str, "default") == 0) + *field_rtrn = F_Default; + else if (uStrCaseCmp(str, "affect") == 0) + *field_rtrn = F_Affect; + else if (uStrCaseCmp(str, "increment") == 0) + *field_rtrn = F_Increment; + else if (uStrCaseCmp(str, "mods") == 0) + *field_rtrn = F_Modifiers; + else if (uStrCaseCmp(str, "modifiers") == 0) + *field_rtrn = F_Modifiers; + else if (uStrCaseCmp(str, "group") == 0) + *field_rtrn = F_Group; + else if (uStrCaseCmp(str, "x") == 0) + *field_rtrn = F_X; + else if (uStrCaseCmp(str, "y") == 0) + *field_rtrn = F_Y; + else if (uStrCaseCmp(str, "accel") == 0) + *field_rtrn = F_Accel; + else if (uStrCaseCmp(str, "accelerate") == 0) + *field_rtrn = F_Accel; + else if (uStrCaseCmp(str, "repeat") == 0) + *field_rtrn = F_Accel; + else if (uStrCaseCmp(str, "button") == 0) + *field_rtrn = F_Button; + else if (uStrCaseCmp(str, "value") == 0) + *field_rtrn = F_Value; + else if (uStrCaseCmp(str, "controls") == 0) + *field_rtrn = F_Controls; + else if (uStrCaseCmp(str, "ctrls") == 0) + *field_rtrn = F_Controls; + else if (uStrCaseCmp(str, "type") == 0) + *field_rtrn = F_Type; + else if (uStrCaseCmp(str, "count") == 0) + *field_rtrn = F_Count; + else if (uStrCaseCmp(str, "screen") == 0) + *field_rtrn = F_Screen; + else if (uStrCaseCmp(str, "same") == 0) + *field_rtrn = F_Same; + else if (uStrCaseCmp(str, "sameserver") == 0) + *field_rtrn = F_Same; + else if (uStrCaseCmp(str, "data") == 0) + *field_rtrn = F_Data; + else if (uStrCaseCmp(str, "device") == 0) + *field_rtrn = F_Device; + else if (uStrCaseCmp(str, "dev") == 0) + *field_rtrn = F_Device; + else if (uStrCaseCmp(str, "key") == 0) + *field_rtrn = F_Keycode; + else if (uStrCaseCmp(str, "keycode") == 0) + *field_rtrn = F_Keycode; + else if (uStrCaseCmp(str, "kc") == 0) + *field_rtrn = F_Keycode; + else if (uStrCaseCmp(str, "clearmods") == 0) + *field_rtrn = F_ModsToClear; + else if (uStrCaseCmp(str, "clearmodifiers") == 0) + *field_rtrn = F_ModsToClear; + else + return False; + return True; +} + +static char * +fieldText(unsigned field) +{ + static char buf[32]; + + switch (field) + { + case F_ClearLocks: + strcpy(buf, "clearLocks"); + break; + case F_LatchToLock: + strcpy(buf, "latchToLock"); + break; + case F_GenKeyEvent: + strcpy(buf, "genKeyEvent"); + break; + case F_Report: + strcpy(buf, "report"); + break; + case F_Default: + strcpy(buf, "default"); + break; + case F_Affect: + strcpy(buf, "affect"); + break; + case F_Increment: + strcpy(buf, "increment"); + break; + case F_Modifiers: + strcpy(buf, "modifiers"); + break; + case F_Group: + strcpy(buf, "group"); + break; + case F_X: + strcpy(buf, "x"); + break; + case F_Y: + strcpy(buf, "y"); + break; + case F_Accel: + strcpy(buf, "accel"); + break; + case F_Button: + strcpy(buf, "button"); + break; + case F_Value: + strcpy(buf, "value"); + break; + case F_Controls: + strcpy(buf, "controls"); + break; + case F_Type: + strcpy(buf, "type"); + break; + case F_Count: + strcpy(buf, "count"); + break; + case F_Screen: + strcpy(buf, "screen"); + break; + case F_Same: + strcpy(buf, "sameServer"); + break; + case F_Data: + strcpy(buf, "data"); + break; + case F_Device: + strcpy(buf, "device"); + break; + case F_Keycode: + strcpy(buf, "keycode"); + break; + case F_ModsToClear: + strcpy(buf, "clearmods"); + break; + default: + strcpy(buf, "unknown"); + break; + } + return buf; +} + +/***====================================================================***/ + +static Bool +ReportMismatch(unsigned action, unsigned field, const char *type) +{ + ERROR2("Value of %s field must be of type %s\n", fieldText(field), type); + ACTION1("Action %s definition ignored\n", + XkbActionTypeText(action, XkbMessage)); + return False; +} + +static Bool +ReportIllegal(unsigned action, unsigned field) +{ + ERROR2("Field %s is not defined for an action of type %s\n", + fieldText(field), XkbActionTypeText(action, XkbMessage)); + ACTION("Action definition ignored\n"); + return False; +} + +static Bool +ReportActionNotArray(unsigned action, unsigned field) +{ + ERROR2("The %s field in the %s action is not an array\n", + fieldText(field), XkbActionTypeText(action, XkbMessage)); + ACTION("Action definition ignored\n"); + return False; +} + +static Bool +ReportNotFound(unsigned action, unsigned field, const char *what, char *bad) +{ + ERROR2("%s named %s not found\n", what, bad); + ACTION2("Ignoring the %s field of an %s action\n", fieldText(field), + XkbActionTypeText(action, XkbMessage)); + return False; +} + +static Bool +HandleNoAction(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + return ReportIllegal(action->type, field); +} + +static Bool +CheckLatchLockFlags(unsigned action, + unsigned field, ExprDef * value, unsigned *flags_inout) +{ + unsigned tmp; + ExprResult result; + + if (field == F_ClearLocks) + tmp = XkbSA_ClearLocks; + else if (field == F_LatchToLock) + tmp = XkbSA_LatchToLock; + else + return False; /* WSGO! */ + if (!ExprResolveBoolean(value, &result, NULL, NULL)) + return ReportMismatch(action, field, "boolean"); + if (result.uval) + *flags_inout |= tmp; + else + *flags_inout &= ~tmp; + return True; +} + +static Bool +CheckModifierField(XkbDescPtr xkb, + unsigned action, + ExprDef * value, + unsigned *flags_inout, unsigned *mods_rtrn) +{ + ExprResult rtrn; + + if (value->op == ExprIdent) + { + register char *valStr; + valStr = XkbAtomGetString(NULL, value->value.str); + if (valStr && ((uStrCaseCmp(valStr, "usemodmapmods") == 0) || + (uStrCaseCmp(valStr, "modmapmods") == 0))) + { + + *mods_rtrn = 0; + *flags_inout |= XkbSA_UseModMapMods; + return True; + } + } + if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb)) + return ReportMismatch(action, F_Modifiers, "modifier mask"); + *mods_rtrn = rtrn.uval; + *flags_inout &= ~XkbSA_UseModMapMods; + return True; +} + +static Bool +HandleSetLatchMods(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + XkbModAction *act; + unsigned rtrn; + unsigned t1, t2; + + act = (XkbModAction *) action; + if (array_ndx != NULL) + { + switch (field) + { + case F_ClearLocks: + case F_LatchToLock: + case F_Modifiers: + return ReportActionNotArray(action->type, field); + } + } + switch (field) + { + case F_ClearLocks: + case F_LatchToLock: + rtrn = act->flags; + if (CheckLatchLockFlags(action->type, field, value, &rtrn)) + { + act->flags = rtrn; + return True; + } + return False; + case F_Modifiers: + t1 = act->flags; + if (CheckModifierField(xkb, action->type, value, &t1, &t2)) + { + act->flags = t1; + act->real_mods = act->mask = (t2 & 0xff); + t2 = (t2 >> 8) & 0xffff; + XkbSetModActionVMods(act, t2); + return True; + } + return False; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleLockMods(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + XkbModAction *act; + unsigned t1, t2; + + act = (XkbModAction *) action; + if ((array_ndx != NULL) && (field == F_Modifiers)) + return ReportActionNotArray(action->type, field); + switch (field) + { + case F_Modifiers: + t1 = act->flags; + if (CheckModifierField(xkb, action->type, value, &t1, &t2)) + { + act->flags = t1; + act->real_mods = act->mask = (t2 & 0xff); + t2 = (t2 >> 8) & 0xffff; + XkbSetModActionVMods(act, t2); + return True; + } + return False; + } + return ReportIllegal(action->type, field); +} + +static LookupEntry groupNames[] = { + {"group1", 1}, + {"group2", 2}, + {"group3", 3}, + {"group4", 4}, + {"group5", 5}, + {"group6", 6}, + {"group7", 7}, + {"group8", 8}, + {NULL, 0}, +}; + +static Bool +CheckGroupField(unsigned action, + ExprDef * value, unsigned *flags_inout, int *grp_rtrn) +{ + ExprDef *spec; + ExprResult rtrn; + + if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) + { + *flags_inout &= ~XkbSA_GroupAbsolute; + spec = value->value.child; + } + else + { + *flags_inout |= XkbSA_GroupAbsolute; + spec = value; + } + + if (!ExprResolveInteger(spec, &rtrn, SimpleLookup, (XPointer) groupNames)) + return ReportMismatch(action, F_Group, "integer (range 1..8)"); + if ((rtrn.ival < 1) || (rtrn.ival > XkbNumKbdGroups)) + { + ERROR2("Illegal group %d (must be in the range 1..%d)\n", rtrn.ival, + XkbNumKbdGroups); + ACTION1("Action %s definition ignored\n", + XkbActionTypeText(action, XkbMessage)); + return False; + } + if (value->op == OpNegate) + *grp_rtrn = -rtrn.ival; + else if (value->op == OpUnaryPlus) + *grp_rtrn = rtrn.ival; + else + *grp_rtrn = rtrn.ival - 1; + return True; +} + +static Bool +HandleSetLatchGroup(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + XkbGroupAction *act; + unsigned rtrn; + unsigned t1; + int t2; + + act = (XkbGroupAction *) action; + if (array_ndx != NULL) + { + switch (field) + { + case F_ClearLocks: + case F_LatchToLock: + case F_Group: + return ReportActionNotArray(action->type, field); + } + } + switch (field) + { + case F_ClearLocks: + case F_LatchToLock: + rtrn = act->flags; + if (CheckLatchLockFlags(action->type, field, value, &rtrn)) + { + act->flags = rtrn; + return True; + } + return False; + case F_Group: + t1 = act->flags; + if (CheckGroupField(action->type, value, &t1, &t2)) + { + act->flags = t1; + XkbSASetGroup(act, t2); + return True; + } + return False; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleLockGroup(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + XkbGroupAction *act; + unsigned t1; + int t2; + + act = (XkbGroupAction *) action; + if ((array_ndx != NULL) && (field == F_Group)) + return ReportActionNotArray(action->type, field); + if (field == F_Group) + { + t1 = act->flags; + if (CheckGroupField(action->type, value, &t1, &t2)) + { + act->flags = t1; + XkbSASetGroup(act, t2); + return True; + } + return False; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleMovePtr(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbPtrAction *act; + Bool absolute; + + act = (XkbPtrAction *) action; + if ((array_ndx != NULL) && ((field == F_X) || (field == F_Y))) + return ReportActionNotArray(action->type, field); + + if ((field == F_X) || (field == F_Y)) + { + if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) + absolute = False; + else + absolute = True; + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "integer"); + if (field == F_X) + { + if (absolute) + act->flags |= XkbSA_MoveAbsoluteX; + XkbSetPtrActionX(act, rtrn.ival); + } + else + { + if (absolute) + act->flags |= XkbSA_MoveAbsoluteY; + XkbSetPtrActionY(act, rtrn.ival); + } + return True; + } + else if (field == F_Accel) + { + if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "boolean"); + if (rtrn.uval) + act->flags &= ~XkbSA_NoAcceleration; + else + act->flags |= XkbSA_NoAcceleration; + } + return ReportIllegal(action->type, field); +} + +static LookupEntry btnNames[] = { + {"button1", 1}, + {"button2", 2}, + {"button3", 3}, + {"button4", 4}, + {"button5", 5}, + {"default", 0}, + {NULL, 0} +}; + +static LookupEntry lockWhich[] = { + {"both", 0}, + {"lock", XkbSA_LockNoUnlock}, + {"neither", (XkbSA_LockNoLock | XkbSA_LockNoUnlock)}, + {"unlock", XkbSA_LockNoLock}, + {NULL, 0} +}; + +static Bool +HandlePtrBtn(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbPtrBtnAction *act; + + act = (XkbPtrBtnAction *) action; + if (field == F_Button) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveInteger + (value, &rtrn, SimpleLookup, (XPointer) btnNames)) + return ReportMismatch(action->type, field, + "integer (range 1..5)"); + if ((rtrn.ival < 0) || (rtrn.ival > 5)) + { + ERROR("Button must specify default or be in the range 1..5\n"); + ACTION1("Illegal button value %d ignored\n", rtrn.ival); + return False; + } + act->button = rtrn.ival; + return True; + } + else if ((action->type == XkbSA_LockPtrBtn) && (field == F_Affect)) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveEnum(value, &rtrn, lockWhich)) + return ReportMismatch(action->type, field, "lock or unlock"); + act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); + act->flags |= rtrn.ival; + return True; + } + else if (field == F_Count) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveInteger + (value, &rtrn, SimpleLookup, (XPointer) btnNames)) + return ReportMismatch(action->type, field, "integer"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("The count field must have a value in the range 0..255\n"); + ACTION1("Illegal count %d ignored\n", rtrn.ival); + return False; + } + act->count = rtrn.ival; + return True; + } + return ReportIllegal(action->type, field); +} + +static LookupEntry ptrDflts[] = { + {"dfltbtn", XkbSA_AffectDfltBtn}, + {"defaultbutton", XkbSA_AffectDfltBtn}, + {"button", XkbSA_AffectDfltBtn}, + {NULL, 0} +}; + +static Bool +HandleSetPtrDflt(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbPtrDfltAction *act; + + act = (XkbPtrDfltAction *) action; + if (field == F_Affect) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveEnum(value, &rtrn, ptrDflts)) + return ReportMismatch(action->type, field, "pointer component"); + act->affect = rtrn.uval; + return True; + } + else if ((field == F_Button) || (field == F_Value)) + { + ExprDef *btn; + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) + { + act->flags &= ~XkbSA_DfltBtnAbsolute; + btn = value->value.child; + } + else + { + act->flags |= XkbSA_DfltBtnAbsolute; + btn = value; + } + + if (!ExprResolveInteger + (btn, &rtrn, SimpleLookup, (XPointer) btnNames)) + return ReportMismatch(action->type, field, + "integer (range 1..5)"); + if ((rtrn.ival < 0) || (rtrn.ival > 5)) + { + ERROR("New default button value must be in the range 1..5\n"); + ACTION1("Illegal default button value %d ignored\n", rtrn.ival); + return False; + } + if (rtrn.ival == 0) + { + ERROR("Cannot set default pointer button to \"default\"\n"); + ACTION("Illegal default button setting ignored\n"); + return False; + } + if (value->op == OpNegate) + XkbSASetPtrDfltValue(act, -rtrn.ival); + else + XkbSASetPtrDfltValue(act, rtrn.ival); + return True; + } + return ReportIllegal(action->type, field); +} + +static LookupEntry isoNames[] = { + {"mods", XkbSA_ISONoAffectMods}, + {"modifiers", XkbSA_ISONoAffectMods}, + {"group", XkbSA_ISONoAffectGroup}, + {"groups", XkbSA_ISONoAffectGroup}, + {"ptr", XkbSA_ISONoAffectPtr}, + {"pointer", XkbSA_ISONoAffectPtr}, + {"ctrls", XkbSA_ISONoAffectCtrls}, + {"controls", XkbSA_ISONoAffectCtrls}, + {"all", ~((unsigned) 0)}, + {"none", 0}, + {NULL, 0}, +}; + +static Bool +HandleISOLock(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbISOAction *act; + unsigned flags, mods; + int group; + + act = (XkbISOAction *) action; + switch (field) + { + case F_Modifiers: + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + flags = act->flags; + if (CheckModifierField(xkb, action->type, value, &flags, &mods)) + { + act->flags = flags & (~XkbSA_ISODfltIsGroup); + act->real_mods = mods & 0xff; + mods = (mods >> 8) & 0xff; + XkbSetModActionVMods(act, mods); + return True; + } + return False; + case F_Group: + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + flags = act->flags; + if (CheckGroupField(action->type, value, &flags, &group)) + { + act->flags = flags | XkbSA_ISODfltIsGroup; + XkbSASetGroup(act, group); + return True; + } + return False; + case F_Affect: + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) isoNames)) + return ReportMismatch(action->type, field, "keyboard component"); + act->affect = (~rtrn.uval) & XkbSA_ISOAffectMask; + return True; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleSwitchScreen(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbSwitchScreenAction *act; + + act = (XkbSwitchScreenAction *) action; + if (field == F_Screen) + { + ExprDef *scrn; + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if ((value->op == OpNegate) || (value->op == OpUnaryPlus)) + { + act->flags &= ~XkbSA_SwitchAbsolute; + scrn = value->value.child; + } + else + { + act->flags |= XkbSA_SwitchAbsolute; + scrn = value; + } + + if (!ExprResolveInteger(scrn, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "integer (0..255)"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("Screen index must be in the range 1..255\n"); + ACTION1("Illegal screen value %d ignored\n", rtrn.ival); + return False; + } + if (value->op == OpNegate) + XkbSASetScreen(act, -rtrn.ival); + else + XkbSASetScreen(act, rtrn.ival); + return True; + } + else if (field == F_Same) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "boolean"); + if (rtrn.uval) + act->flags &= ~XkbSA_SwitchApplication; + else + act->flags |= XkbSA_SwitchApplication; + return True; + } + return ReportIllegal(action->type, field); +} + +LookupEntry ctrlNames[] = { + {"repeatkeys", XkbRepeatKeysMask} + , + {"repeat", XkbRepeatKeysMask} + , + {"autorepeat", XkbRepeatKeysMask} + , + {"slowkeys", XkbSlowKeysMask} + , + {"bouncekeys", XkbBounceKeysMask} + , + {"stickykeys", XkbStickyKeysMask} + , + {"mousekeys", XkbMouseKeysMask} + , + {"mousekeysaccel", XkbMouseKeysAccelMask} + , + {"accessxkeys", XkbAccessXKeysMask} + , + {"accessxtimeout", XkbAccessXTimeoutMask} + , + {"accessxfeedback", XkbAccessXFeedbackMask} + , + {"audiblebell", XkbAudibleBellMask} + , + {"overlay1", XkbOverlay1Mask} + , + {"overlay2", XkbOverlay2Mask} + , + {"ignoregrouplock", XkbIgnoreGroupLockMask} + , + {"all", XkbAllBooleanCtrlsMask} + , + {"none", 0} + , + {NULL, 0} +}; + +static Bool +HandleSetLockControls(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbCtrlsAction *act; + + act = (XkbCtrlsAction *) action; + if (field == F_Controls) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveMask + (value, &rtrn, SimpleLookup, (XPointer) ctrlNames)) + return ReportMismatch(action->type, field, "controls mask"); + XkbActionSetCtrls(act, rtrn.uval); + return True; + } + return ReportIllegal(action->type, field); +} + +static LookupEntry evNames[] = { + {"press", XkbSA_MessageOnPress}, + {"keypress", XkbSA_MessageOnPress}, + {"release", XkbSA_MessageOnRelease}, + {"keyrelease", XkbSA_MessageOnRelease}, + {"all", XkbSA_MessageOnPress | XkbSA_MessageOnRelease}, + {"none", 0}, + {NULL, 0} +}; + +static Bool +HandleActionMessage(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbMessageAction *act; + + act = (XkbMessageAction *) action; + switch (field) + { + case F_Report: + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveMask(value, &rtrn, SimpleLookup, (XPointer) evNames)) + return ReportMismatch(action->type, field, "key event mask"); + act->flags &= ~(XkbSA_MessageOnPress | XkbSA_MessageOnRelease); + act->flags = + rtrn.uval & (XkbSA_MessageOnPress | XkbSA_MessageOnRelease); + return True; + case F_GenKeyEvent: + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "boolean"); + if (rtrn.uval) + act->flags |= XkbSA_MessageGenKeyEvent; + else + act->flags &= ~XkbSA_MessageGenKeyEvent; + return True; + case F_Data: + if (array_ndx == NULL) + { + if (!ExprResolveString(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "string"); + else + { + int len = strlen(rtrn.str); + if ((len < 1) || (len > 6)) + { + WARN("An action message can hold only 6 bytes\n"); + ACTION1("Extra %d bytes ignored\n", len - 6); + } + strncpy((char *) act->message, rtrn.str, 6); + } + return True; + } + else + { + unsigned ndx; + if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL)) + { + ERROR("Array subscript must be integer\n"); + ACTION("Illegal subscript ignored\n"); + return False; + } + ndx = rtrn.uval; + if (ndx > 5) + { + ERROR("An action message is at most 6 bytes long\n"); + ACTION1("Attempt to use data[%d] ignored\n", ndx); + return False; + } + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "integer"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("Message data must be in the range 0..255\n"); + ACTION1("Illegal datum %d ignored\n", rtrn.ival); + return False; + } + act->message[ndx] = rtrn.uval; + } + return True; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleRedirectKey(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbRedirectKeyAction *act; + unsigned t1, t2, vmods, vmask; + unsigned long tmp; + + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + + act = (XkbRedirectKeyAction *) action; + switch (field) + { + case F_Keycode: + if (!ExprResolveKeyName(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "key name"); + tmp = KeyNameToLong(rtrn.keyName.name); + if (!FindNamedKey(xkb, tmp, &t1, True, CreateKeyNames(xkb), 0)) + { + return ReportNotFound(action->type, field, "Key", + XkbKeyNameText(rtrn.keyName.name, + XkbMessage)); + } + act->new_key = t1; + return True; + case F_ModsToClear: + case F_Modifiers: + t1 = 0; + if (CheckModifierField(xkb, action->type, value, &t1, &t2)) + { + act->mods_mask |= (t2 & 0xff); + if (field == F_Modifiers) + act->mods |= (t2 & 0xff); + else + act->mods &= ~(t2 & 0xff); + + t2 = (t2 >> 8) & 0xffff; + vmods = XkbSARedirectVMods(act); + vmask = XkbSARedirectVModsMask(act); + vmask |= t2; + if (field == F_Modifiers) + vmods |= t2; + else + vmods &= ~t2; + XkbSARedirectSetVMods(act, vmods); + XkbSARedirectSetVModsMask(act, vmask); + return True; + } + return True; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleDeviceBtn(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + XkbDeviceBtnAction *act; + + act = (XkbDeviceBtnAction *) action; + if (field == F_Button) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, + "integer (range 1..255)"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("Button must specify default or be in the range 1..255\n"); + ACTION1("Illegal button value %d ignored\n", rtrn.ival); + return False; + } + act->button = rtrn.ival; + return True; + } + else if ((action->type == XkbSA_LockDeviceBtn) && (field == F_Affect)) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveEnum(value, &rtrn, lockWhich)) + return ReportMismatch(action->type, field, "lock or unlock"); + act->flags &= ~(XkbSA_LockNoLock | XkbSA_LockNoUnlock); + act->flags |= rtrn.ival; + return True; + } + else if (field == F_Count) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveInteger + (value, &rtrn, SimpleLookup, (XPointer) btnNames)) + return ReportMismatch(action->type, field, "integer"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("The count field must have a value in the range 0..255\n"); + ACTION1("Illegal count %d ignored\n", rtrn.ival); + return False; + } + act->count = rtrn.ival; + return True; + } + else if (field == F_Device) + { + if (array_ndx != NULL) + return ReportActionNotArray(action->type, field); + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, + "integer (range 1..255)"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("Device must specify default or be in the range 1..255\n"); + ACTION1("Illegal device value %d ignored\n", rtrn.ival); + return False; + } + act->device = rtrn.ival; + return True; + } + return ReportIllegal(action->type, field); +} + +static Bool +HandleDeviceValuator(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ +#if 0 + ExprResult rtrn; + XkbDeviceValuatorAction *act; + + act = (XkbDeviceValuatorAction *) action; + /* XXX - Not yet implemented */ +#endif + return False; +} + +static Bool +HandlePrivate(XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, ExprDef * array_ndx, ExprDef * value) +{ + ExprResult rtrn; + + switch (field) + { + case F_Type: + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(PrivateAction, field, "integer"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("Private action type must be in the range 0..255\n"); + ACTION1("Illegal type %d ignored\n", rtrn.ival); + return False; + } + action->type = rtrn.uval; + return True; + case F_Data: + if (array_ndx == NULL) + { + if (!ExprResolveString(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "string"); + else + { + int len = strlen(rtrn.str); + if ((len < 1) || (len > 7)) + { + WARN("A private action has 7 data bytes\n"); + ACTION1("Extra %d bytes ignored\n", len - 6); + return False; + } + strncpy((char *) action->data, rtrn.str, 7); + } + return True; + } + else + { + unsigned ndx; + if (!ExprResolveInteger(array_ndx, &rtrn, NULL, NULL)) + { + ERROR("Array subscript must be integer\n"); + ACTION("Illegal subscript ignored\n"); + return False; + } + ndx = rtrn.uval; + if (ndx > 6) + { + ERROR("The data for a private action is 7 bytes long\n"); + ACTION1("Attempt to use data[%d] ignored\n", ndx); + return False; + } + if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) + return ReportMismatch(action->type, field, "integer"); + if ((rtrn.ival < 0) || (rtrn.ival > 255)) + { + ERROR("All data for a private action must be 0..255\n"); + ACTION1("Illegal datum %d ignored\n", rtrn.ival); + return False; + } + action->data[ndx] = rtrn.uval; + return True; + } + } + return ReportIllegal(PrivateAction, field); +} + +typedef Bool(*actionHandler) (XkbDescPtr /* xkb */ , + XkbAnyAction * /* action */ , + unsigned /* field */ , + ExprDef * /* array_ndx */ , + ExprDef * /* value */ + ); + +static actionHandler handleAction[XkbSA_NumActions + 1] = { + HandleNoAction /* NoAction */ , + HandleSetLatchMods /* SetMods */ , + HandleSetLatchMods /* LatchMods */ , + HandleLockMods /* LockMods */ , + HandleSetLatchGroup /* SetGroup */ , + HandleSetLatchGroup /* LatchGroup */ , + HandleLockGroup /* LockGroup */ , + HandleMovePtr /* MovePtr */ , + HandlePtrBtn /* PtrBtn */ , + HandlePtrBtn /* LockPtrBtn */ , + HandleSetPtrDflt /* SetPtrDflt */ , + HandleISOLock /* ISOLock */ , + HandleNoAction /* Terminate */ , + HandleSwitchScreen /* SwitchScreen */ , + HandleSetLockControls /* SetControls */ , + HandleSetLockControls /* LockControls */ , + HandleActionMessage /* ActionMessage */ , + HandleRedirectKey /* RedirectKey */ , + HandleDeviceBtn /* DeviceBtn */ , + HandleDeviceBtn /* LockDeviceBtn */ , + HandleDeviceValuator /* DeviceValuatr */ , + HandlePrivate /* Private */ +}; + +/***====================================================================***/ + +static void +ApplyActionFactoryDefaults(XkbAction * action) +{ + if (action->type == XkbSA_SetPtrDflt) + { /* increment default button */ + action->dflt.affect = XkbSA_AffectDfltBtn; + action->dflt.flags = 0; + XkbSASetPtrDfltValue(&action->dflt, 1); + } + else if (action->type == XkbSA_ISOLock) + { + action->iso.real_mods = LockMask; + } + return; +} + + +int +HandleActionDef(ExprDef * def, + XkbDescPtr xkb, + XkbAnyAction * action, unsigned mergeMode, ActionInfo * info) +{ + ExprDef *arg; + register char *str; + unsigned tmp, hndlrType; + + if (!actionsInitialized) + ActionsInit(); + + if (def->op != ExprActionDecl) + { + ERROR1("Expected an action definition, found %s\n", + exprOpText(def->op)); + return False; + } + str = XkbAtomGetString(NULL, def->value.action.name); + if (!str) + { + WSGO("Missing name in action definition!!\n"); + return False; + } + if (!stringToAction(str, &tmp)) + { + ERROR1("Unknown action %s\n", str); + return False; + } + action->type = hndlrType = tmp; + if (action->type != XkbSA_NoAction) + { + ApplyActionFactoryDefaults((XkbAction *) action); + while (info) + { + if ((info->action == XkbSA_NoAction) + || (info->action == hndlrType)) + { + if (!(*handleAction[hndlrType]) (xkb, action, + info->field, + info->array_ndx, + info->value)) + { + return False; + } + } + info = info->next; + } + } + for (arg = def->value.action.args; arg != NULL; + arg = (ExprDef *) arg->common.next) + { + ExprDef *field, *value, *arrayRtrn; + ExprResult elemRtrn, fieldRtrn; + unsigned fieldNdx; + + if (arg->op == OpAssign) + { + field = arg->value.binary.left; + value = arg->value.binary.right; + } + else + { + if ((arg->op == OpNot) || (arg->op == OpInvert)) + { + field = arg->value.child; + value = &constFalse; + } + else + { + field = arg; + value = &constTrue; + } + } + if (!ExprResolveLhs(field, &elemRtrn, &fieldRtrn, &arrayRtrn)) + return False; /* internal error -- already reported */ + + if (elemRtrn.str != NULL) + { + ERROR("Cannot change defaults in an action definition\n"); + ACTION2("Ignoring attempt to change %s.%s\n", elemRtrn.str, + fieldRtrn.str); + return False; + } + if (!stringToField(fieldRtrn.str, &fieldNdx)) + { + ERROR1("Unknown field name %s\n", uStringText(fieldRtrn.str)); + return False; + } + if (!(*handleAction[hndlrType]) + (xkb, action, fieldNdx, arrayRtrn, value)) + { + return False; + } + } + return True; +} + +/***====================================================================***/ + +int +SetActionField(XkbDescPtr xkb, + char *elem, + char *field, + ExprDef * array_ndx, ExprDef * value, ActionInfo ** info_rtrn) +{ + ActionInfo *new, *old; + + if (!actionsInitialized) + ActionsInit(); + + new = uTypedAlloc(ActionInfo); + if (new == NULL) + { + WSGO("Couldn't allocate space for action default\n"); + return False; + } + if (uStrCaseCmp(elem, "action") == 0) + new->action = XkbSA_NoAction; + else + { + if (!stringToAction(elem, &new->action)) + return False; + if (new->action == XkbSA_NoAction) + { + ERROR1("\"%s\" is not a valid field in a NoAction action\n", + field); + return False; + } + } + if (!stringToField(field, &new->field)) + { + ERROR1("\"%s\" is not a legal field name\n", field); + return False; + } + new->array_ndx = array_ndx; + new->value = value; + new->next = NULL; + old = *info_rtrn; + while ((old) && (old->next)) + old = old->next; + if (old == NULL) + *info_rtrn = new; + else + old->next = new; + return True; +} + +/***====================================================================***/ + +void +ActionsInit(void) +{ + if (!actionsInitialized) + { + bzero((char *) &constTrue, sizeof(constTrue)); + bzero((char *) &constFalse, sizeof(constFalse)); + constTrue.common.stmtType = StmtExpr; + constTrue.common.next = NULL; + constTrue.op = ExprIdent; + constTrue.type = TypeBoolean; + constTrue.value.str = XkbInternAtom(NULL, "true", False); + constFalse.common.stmtType = StmtExpr; + constFalse.common.next = NULL; + constFalse.op = ExprIdent; + constFalse.type = TypeBoolean; + constFalse.value.str = XkbInternAtom(NULL, "false", False); + actionsInitialized = 1; + } + return; +} diff --git a/xkbcomp/action.h b/xkbcomp/action.h index 61666e8a1..2fb7a5eb9 100644 --- a/xkbcomp/action.h +++ b/xkbcomp/action.h @@ -1,86 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/alias.h b/xkbcomp/alias.h index 7603c273c..b6fac5bfa 100644 --- a/xkbcomp/alias.h +++ b/xkbcomp/alias.h @@ -1,56 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/autogen.sh b/xkbcomp/autogen.sh index f55f8fb7b..e81f98910 100644 --- a/xkbcomp/autogen.sh +++ b/xkbcomp/autogen.sh @@ -1,13 +1,13 @@ -#! /bin/sh
-
-srcdir=`dirname $0`
-test -z "$srcdir" && srcdir=.
-
-ORIGDIR=`pwd`
-cd $srcdir
-
-autoreconf -v --install || exit 1
-cd $ORIGDIR || exit $?
-
-$srcdir/configure --enable-maintainer-mode "$@"
-
+#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" + diff --git a/xkbcomp/compat.h b/xkbcomp/compat.h index 702883275..799b215ee 100644 --- a/xkbcomp/compat.h +++ b/xkbcomp/compat.h @@ -1,7 +1,7 @@ -
-#ifndef COMPAT_H
-#define COMPAT_H 1
-
-extern LookupEntry groupNames[];
-
-#endif /* COMPAT_H */
+ +#ifndef COMPAT_H +#define COMPAT_H 1 + +extern LookupEntry groupNames[]; + +#endif /* COMPAT_H */ diff --git a/xkbcomp/expr.c b/xkbcomp/expr.c index 33a2dddee..96fd95675 100644 --- a/xkbcomp/expr.c +++ b/xkbcomp/expr.c @@ -1,1065 +1,1065 @@ -/************************************************************
- 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 <ctype.h>
-
-/***====================================================================***/
-
-char *
-exprOpText(unsigned type)
-{
- static char buf[32];
-
- switch (type)
- {
- case ExprValue:
- strcpy(buf, "literal");
- break;
- case ExprIdent:
- strcpy(buf, "identifier");
- break;
- case ExprActionDecl:
- strcpy(buf, "action declaration");
- break;
- case ExprFieldRef:
- strcpy(buf, "field reference");
- break;
- case ExprArrayRef:
- strcpy(buf, "array reference");
- break;
- case ExprKeysymList:
- strcpy(buf, "list of keysyms");
- break;
- case ExprActionList:
- strcpy(buf, "list of actions");
- break;
- case OpAdd:
- strcpy(buf, "addition");
- break;
- case OpSubtract:
- strcpy(buf, "subtraction");
- break;
- case OpMultiply:
- strcpy(buf, "multiplication");
- break;
- case OpDivide:
- strcpy(buf, "division");
- break;
- case OpAssign:
- strcpy(buf, "assignment");
- break;
- case OpNot:
- strcpy(buf, "logical not");
- break;
- case OpNegate:
- strcpy(buf, "arithmetic negation");
- break;
- case OpInvert:
- strcpy(buf, "bitwise inversion");
- break;
- case OpUnaryPlus:
- strcpy(buf, "plus sign");
- break;
- default:
- snprintf(buf, sizeof(buf), "illegal(%d)", type);
- break;
- }
- return buf;
-}
-
-char *
-exprTypeText(unsigned type)
-{
- static char buf[20];
-
- switch (type)
- {
- case TypeUnknown:
- strcpy(buf, "unknown");
- break;
- case TypeBoolean:
- strcpy(buf, "boolean");
- break;
- case TypeInt:
- strcpy(buf, "int");
- break;
- case TypeString:
- strcpy(buf, "string");
- break;
- case TypeAction:
- strcpy(buf, "action");
- break;
- case TypeKeyName:
- strcpy(buf, "keyname");
- break;
- default:
- snprintf(buf, sizeof(buf), "illegal(%d)", type);
- break;
- }
- return buf;
-}
-
-int
-ExprResolveLhs(ExprDef * expr,
- ExprResult * elem_rtrn,
- ExprResult * field_rtrn, ExprDef ** index_rtrn)
-{
- switch (expr->op)
- {
- case ExprIdent:
- elem_rtrn->str = NULL;
- field_rtrn->str = XkbAtomGetString(NULL, expr->value.str);
- *index_rtrn = NULL;
- return True;
- case ExprFieldRef:
- elem_rtrn->str = XkbAtomGetString(NULL, expr->value.field.element);
- field_rtrn->str = XkbAtomGetString(NULL, expr->value.field.field);
- *index_rtrn = NULL;
- return True;
- case ExprArrayRef:
- elem_rtrn->str = XkbAtomGetString(NULL, expr->value.array.element);
- field_rtrn->str = XkbAtomGetString(NULL, expr->value.array.field);
- *index_rtrn = expr->value.array.entry;
- return True;
- }
- WSGO1("Unexpected operator %d in ResolveLhs\n", expr->op);
- return False;
-}
-
-Bool
-SimpleLookup(XPointer priv,
- Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
-{
- LookupEntry *entry;
- register char *str;
-
- if ((priv == NULL) ||
- (field == None) || (elem != None) ||
- ((type != TypeInt) && (type != TypeFloat)))
- {
- return False;
- }
- str = XkbAtomGetString(NULL, field);
- for (entry = (LookupEntry *) priv;
- (entry != NULL) && (entry->name != NULL); entry++)
- {
- if (uStrCaseCmp(str, entry->name) == 0)
- {
- val_rtrn->uval = entry->result;
- if (type == TypeFloat)
- val_rtrn->uval *= XkbGeomPtsPerMM;
- return True;
- }
- }
- return False;
-}
-
-Bool
-RadioLookup(XPointer priv,
- Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
-{
- register char *str;
- int rg;
-
- if ((field == None) || (elem != None) || (type != TypeInt))
- return False;
- str = XkbAtomGetString(NULL, field);
- if (str)
- {
- if (uStrCasePrefix("group", str))
- str += strlen("group");
- else if (uStrCasePrefix("radiogroup", str))
- str += strlen("radiogroup");
- else if (uStrCasePrefix("rg", str))
- str += strlen("rg");
- else if (!isdigit(str[0]))
- str = NULL;
- }
- if ((!str) || (sscanf(str, "%i", &rg) < 1) || (rg < 1)
- || (rg > XkbMaxRadioGroups))
- return False;
- val_rtrn->uval = rg;
- return True;
-}
-
-int
-TableLookup(XPointer priv,
- Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
-{
- LookupTable *tbl = (LookupTable *) priv;
- register char *str;
-
- if ((priv == NULL) || (field == None) || (type != TypeInt))
- return False;
- str = XkbAtomGetString(NULL, elem);
- while (tbl)
- {
- if (((str == NULL) && (tbl->element == NULL)) ||
- ((str != NULL) && (tbl->element != NULL) &&
- (uStrCaseCmp(str, tbl->element) == 0)))
- {
- break;
- }
- tbl = tbl->nextElement;
- }
- if (tbl == NULL) /* didn't find a matching element */
- return False;
- priv = (XPointer) tbl->entries;
- return SimpleLookup(priv, (Atom) None, field, type, val_rtrn);
-}
-
-static LookupEntry modIndexNames[] = {
- {"shift", ShiftMapIndex},
- {"control", ControlMapIndex},
- {"lock", LockMapIndex},
- {"mod1", Mod1MapIndex},
- {"mod2", Mod2MapIndex},
- {"mod3", Mod3MapIndex},
- {"mod4", Mod4MapIndex},
- {"mod5", Mod5MapIndex},
- {"none", XkbNoModifier},
- {NULL, 0}
-};
-
-int
-LookupModIndex(XPointer priv,
- Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
-{
- return SimpleLookup((XPointer) modIndexNames, elem, field, type,
- val_rtrn);
-}
-
-int
-LookupModMask(XPointer priv,
- Atom elem, Atom field, unsigned type, ExprResult * val_rtrn)
-{
- char *str;
-
- if ((elem != None) || (type != TypeInt))
- return False;
- str = XkbAtomGetString(NULL, field);
- if (str == NULL)
- return False;
- if (uStrCaseCmp(str, "all") == 0)
- val_rtrn->uval = 0xff;
- else if (uStrCaseCmp(str, "none") == 0)
- val_rtrn->uval = 0;
- else if (LookupModIndex(priv, elem, field, type, val_rtrn))
- val_rtrn->uval = (1 << val_rtrn->uval);
- else if (priv != NULL)
- {
- LookupPriv *lpriv = (LookupPriv *) priv;
- if ((lpriv->chain == NULL) ||
- (!(*lpriv->chain) (lpriv->chainPriv, elem, field, type,
- val_rtrn)))
- return False;
- }
- else
- return False;
- return True;
-}
-
-int
-ExprResolveModIndex(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- char *bogus = NULL;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type != TypeInt)
- {
- ERROR1
- ("Found constant of type %s where a modifier mask was expected\n",
- exprTypeText(expr->type));
- return False;
- }
- else if ((expr->value.ival >= XkbNumModifiers)
- || (expr->value.ival < 0))
- {
- ERROR2("Illegal modifier index (%d, must be 0..%d)\n",
- expr->value.ival, XkbNumModifiers - 1);
- return False;
- }
- val_rtrn->ival = expr->value.ival;
- return True;
- case ExprIdent:
- if (LookupModIndex(lookupPriv, (Atom) None, expr->value.str,
- (unsigned) TypeInt, val_rtrn))
- {
- return True;
- }
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeInt, val_rtrn);
- }
- if (!ok)
- ERROR1("Cannot determine modifier index for \"%s\"\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- break;
- case ExprFieldRef:
- bogus = "field reference";
- break;
- case ExprArrayRef:
- bogus = "array reference";
- break;
- case ExprActionDecl:
- bogus = "function";
- break;
- case OpAdd:
- case OpSubtract:
- case OpMultiply:
- case OpDivide:
- case OpInvert:
- case OpNegate:
- case OpNot:
- case OpUnaryPlus:
- bogus = "arithmetic operations";
- break;
- case OpAssign:
- bogus = "assignment";
- break;
- default:
- WSGO1("Unknown operator %d in ResolveModIndex\n", expr->op);
- return False;
- }
- if (bogus)
- {
- ERROR1("Modifier index must be a name or number, %s ignored\n",
- bogus);
- return False;
- }
- return ok;
-}
-
-int
-ExprResolveModMask(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- LookupPriv priv;
-
- priv.priv = NULL;
- priv.chain = lookup;
- priv.chainPriv = lookupPriv;
- return ExprResolveMask(expr, val_rtrn, LookupModMask, (XPointer) & priv);
-}
-
-int
-ExprResolveBoolean(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- char *bogus = NULL;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type != TypeBoolean)
- {
- ERROR1
- ("Found constant of type %s where boolean was expected\n",
- exprTypeText(expr->type));
- return False;
- }
- val_rtrn->ival = expr->value.ival;
- return True;
- case ExprIdent:
- bogus = XkbAtomGetString(NULL, expr->value.str);
- if (bogus)
- {
- if ((uStrCaseCmp(bogus, "true") == 0) ||
- (uStrCaseCmp(bogus, "yes") == 0) ||
- (uStrCaseCmp(bogus, "on") == 0))
- {
- val_rtrn->uval = 1;
- return True;
- }
- else if ((uStrCaseCmp(bogus, "false") == 0) ||
- (uStrCaseCmp(bogus, "no") == 0) ||
- (uStrCaseCmp(bogus, "off") == 0))
- {
- val_rtrn->uval = 0;
- return True;
- }
- }
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeBoolean, val_rtrn);
- }
- if (!ok)
- ERROR1("Identifier \"%s\" of type int is unknown\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeBoolean, val_rtrn);
- }
- if (!ok)
- ERROR2("Default \"%s.%s\" of type boolean is unknown\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case OpInvert:
- case OpNot:
- ok = ExprResolveBoolean(expr, val_rtrn, lookup, lookupPriv);
- if (ok)
- val_rtrn->uval = !val_rtrn->uval;
- return ok;
- case OpAdd:
- if (bogus == NULL)
- bogus = "Addition";
- case OpSubtract:
- if (bogus == NULL)
- bogus = "Subtraction";
- case OpMultiply:
- if (bogus == NULL)
- bogus = "Multiplication";
- case OpDivide:
- if (bogus == NULL)
- bogus = "Division";
- case OpAssign:
- if (bogus == NULL)
- bogus = "Assignment";
- case OpNegate:
- if (bogus == NULL)
- bogus = "Negation";
- ERROR1("%s of boolean values not permitted\n", bogus);
- break;
- case OpUnaryPlus:
- ERROR("Unary \"+\" operator not permitted for boolean values\n");
- break;
- default:
- WSGO1("Unknown operator %d in ResolveBoolean\n", expr->op);
- break;
- }
- return False;
-}
-
-int
-ExprResolveFloat(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- ExprResult leftRtrn, rightRtrn;
- ExprDef *left, *right;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type == TypeString)
- {
- register char *str;
- str = XkbAtomGetString(NULL, expr->value.str);
- if ((str != NULL) && (strlen(str) == 1))
- {
- val_rtrn->uval = str[0] * XkbGeomPtsPerMM;
- return True;
- }
- }
- if ((expr->type != TypeInt) && (expr->type != TypeFloat))
- {
- ERROR1("Found constant of type %s, expected a number\n",
- exprTypeText(expr->type));
- return False;
- }
- val_rtrn->ival = expr->value.ival;
- if (expr->type == TypeInt)
- val_rtrn->ival *= XkbGeomPtsPerMM;
- return True;
- case ExprIdent:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeFloat, val_rtrn);
- }
- if (!ok)
- ERROR1("Numeric identifier \"%s\" unknown\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeFloat, val_rtrn);
- }
- if (!ok)
- ERROR2("Numeric default \"%s.%s\" unknown\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case OpAdd:
- case OpSubtract:
- case OpMultiply:
- case OpDivide:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
- if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv) &&
- ExprResolveFloat(right, &rightRtrn, lookup, lookupPriv))
- {
- switch (expr->op)
- {
- case OpAdd:
- val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
- break;
- case OpSubtract:
- val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
- break;
- case OpMultiply:
- val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
- break;
- case OpDivide:
- val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
- break;
- }
- return True;
- }
- return False;
- case OpAssign:
- WSGO("Assignment operator not implemented yet\n");
- break;
- case OpNot:
- left = expr->value.child;
- if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The ! operator cannot be applied to a number\n");
- }
- return False;
- case OpInvert:
- case OpNegate:
- left = expr->value.child;
- if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv))
- {
- if (expr->op == OpNegate)
- val_rtrn->ival = -leftRtrn.ival;
- else
- val_rtrn->ival = ~leftRtrn.ival;
- return True;
- }
- return False;
- case OpUnaryPlus:
- left = expr->value.child;
- return ExprResolveFloat(left, val_rtrn, lookup, lookupPriv);
- default:
- WSGO1("Unknown operator %d in ResolveFloat\n", expr->op);
- break;
- }
- return False;
-}
-
-int
-ExprResolveInteger(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- ExprResult leftRtrn, rightRtrn;
- ExprDef *left, *right;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type == TypeString)
- {
- register char *str;
- str = XkbAtomGetString(NULL, expr->value.str);
- if (str != NULL)
- switch (strlen(str))
- {
- case 0:
- val_rtrn->uval = 0;
- return True;
- case 1:
- val_rtrn->uval = str[0];
- return True;
- default:
- break;
- }
- }
- if ((expr->type != TypeInt) && (expr->type != TypeFloat))
- {
- ERROR1
- ("Found constant of type %s where an int was expected\n",
- exprTypeText(expr->type));
- return False;
- }
- val_rtrn->ival = expr->value.ival;
- if (expr->type == TypeFloat)
- val_rtrn->ival /= XkbGeomPtsPerMM;
- return True;
- case ExprIdent:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeInt, val_rtrn);
- }
- if (!ok)
- ERROR1("Identifier \"%s\" of type int is unknown\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeInt, val_rtrn);
- }
- if (!ok)
- ERROR2("Default \"%s.%s\" of type int is unknown\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case OpAdd:
- case OpSubtract:
- case OpMultiply:
- case OpDivide:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
- if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv) &&
- ExprResolveInteger(right, &rightRtrn, lookup, lookupPriv))
- {
- switch (expr->op)
- {
- case OpAdd:
- val_rtrn->ival = leftRtrn.ival + rightRtrn.ival;
- break;
- case OpSubtract:
- val_rtrn->ival = leftRtrn.ival - rightRtrn.ival;
- break;
- case OpMultiply:
- val_rtrn->ival = leftRtrn.ival * rightRtrn.ival;
- break;
- case OpDivide:
- val_rtrn->ival = leftRtrn.ival / rightRtrn.ival;
- break;
- }
- return True;
- }
- return False;
- case OpAssign:
- WSGO("Assignment operator not implemented yet\n");
- break;
- case OpNot:
- left = expr->value.child;
- if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The ! operator cannot be applied to an integer\n");
- }
- return False;
- case OpInvert:
- case OpNegate:
- left = expr->value.child;
- if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
- {
- if (expr->op == OpNegate)
- val_rtrn->ival = -leftRtrn.ival;
- else
- val_rtrn->ival = ~leftRtrn.ival;
- return True;
- }
- return False;
- case OpUnaryPlus:
- left = expr->value.child;
- return ExprResolveInteger(left, val_rtrn, lookup, lookupPriv);
- default:
- WSGO1("Unknown operator %d in ResolveInteger\n", expr->op);
- break;
- }
- return False;
-}
-
-int
-ExprResolveString(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- ExprResult leftRtrn, rightRtrn;
- ExprDef *left;
- ExprDef *right;
- char *bogus = NULL;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type != TypeString)
- {
- ERROR1("Found constant of type %s, expected a string\n",
- exprTypeText(expr->type));
- return False;
- }
- val_rtrn->str = XkbAtomGetString(NULL, expr->value.str);
- if (val_rtrn->str == NULL)
- {
- static char *empty = "";
- val_rtrn->str = empty;
- }
- return True;
- case ExprIdent:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeString, val_rtrn);
- }
- if (!ok)
- ERROR1("Identifier \"%s\" of type string not found\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeString, val_rtrn);
- }
- if (!ok)
- ERROR2("Default \"%s.%s\" of type string not found\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case OpAdd:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
- if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv) &&
- ExprResolveString(right, &rightRtrn, lookup, lookupPriv))
- {
- int len;
- char *new;
- len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1;
- new = (char *) uAlloc(len);
- if (new)
- {
- sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str);
- val_rtrn->str = new;
- return True;
- }
- }
- return False;
- case OpSubtract:
- if (bogus == NULL)
- bogus = "Subtraction";
- case OpMultiply:
- if (bogus == NULL)
- bogus = "Multiplication";
- case OpDivide:
- if (bogus == NULL)
- bogus = "Division";
- case OpAssign:
- if (bogus == NULL)
- bogus = "Assignment";
- case OpNegate:
- if (bogus == NULL)
- bogus = "Negation";
- case OpInvert:
- if (bogus == NULL)
- bogus = "Bitwise complement";
- ERROR1("%s of string values not permitted\n", bogus);
- return False;
- case OpNot:
- left = expr->value.child;
- if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The ! operator cannot be applied to a string\n");
- }
- return False;
- case OpUnaryPlus:
- left = expr->value.child;
- if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The + operator cannot be applied to a string\n");
- }
- return False;
- default:
- WSGO1("Unknown operator %d in ResolveString\n", expr->op);
- break;
- }
- return False;
-}
-
-int
-ExprResolveKeyName(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- ExprDef *left;
- ExprResult leftRtrn;
- char *bogus = NULL;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type != TypeKeyName)
- {
- ERROR1("Found constant of type %s, expected a key name\n",
- exprTypeText(expr->type));
- return False;
- }
- memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength);
- return True;
- case ExprIdent:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeString, val_rtrn);
- }
- if (!ok)
- ERROR1("Identifier \"%s\" of type string not found\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeString, val_rtrn);
- }
- if (!ok)
- ERROR2("Default \"%s.%s\" of type key name not found\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case OpAdd:
- if (bogus == NULL)
- bogus = "Addition";
- case OpSubtract:
- if (bogus == NULL)
- bogus = "Subtraction";
- case OpMultiply:
- if (bogus == NULL)
- bogus = "Multiplication";
- case OpDivide:
- if (bogus == NULL)
- bogus = "Division";
- case OpAssign:
- if (bogus == NULL)
- bogus = "Assignment";
- case OpNegate:
- if (bogus == NULL)
- bogus = "Negation";
- case OpInvert:
- if (bogus == NULL)
- bogus = "Bitwise complement";
- ERROR1("%s of key name values not permitted\n", bogus);
- return False;
- case OpNot:
- left = expr->value.binary.left;
- if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The ! operator cannot be applied to a key name\n");
- }
- return False;
- case OpUnaryPlus:
- left = expr->value.binary.left;
- if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR("The + operator cannot be applied to a key name\n");
- }
- return False;
- default:
- WSGO1("Unknown operator %d in ResolveKeyName\n", expr->op);
- break;
- }
- return False;
-}
-
-/***====================================================================***/
-
-int
-ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values)
-{
- if (expr->op != ExprIdent)
- {
- ERROR1("Found a %s where an enumerated value was expected\n",
- exprOpText(expr->op));
- return False;
- }
- if (!SimpleLookup((XPointer) values, (Atom) None, expr->value.str,
- (unsigned) TypeInt, val_rtrn))
- {
- int nOut = 0;
- ERROR1("Illegal identifier %s (expected one of: ",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- while (values && values->name)
- {
- if (nOut != 0)
- INFO1(", %s", values->name);
- else
- INFO1("%s", values->name);
- values++;
- nOut++;
- }
- INFO(")\n");
- return False;
- }
- return True;
-}
-
-int
-ExprResolveMask(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- ExprResult leftRtrn, rightRtrn;
- ExprDef *left, *right;
- char *bogus = NULL;
-
- switch (expr->op)
- {
- case ExprValue:
- if (expr->type != TypeInt)
- {
- ERROR1
- ("Found constant of type %s where a mask was expected\n",
- exprTypeText(expr->type));
- return False;
- }
- val_rtrn->ival = expr->value.ival;
- return True;
- case ExprIdent:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- None, expr->value.str, TypeInt, val_rtrn);
- }
- if (!ok)
- ERROR1("Identifier \"%s\" of type int is unknown\n",
- XkbAtomText(NULL, expr->value.str, XkbMessage));
- return ok;
- case ExprFieldRef:
- if (lookup)
- {
- ok = (*lookup) (lookupPriv,
- expr->value.field.element,
- expr->value.field.field, TypeInt, val_rtrn);
- }
- if (!ok)
- ERROR2("Default \"%s.%s\" of type int is unknown\n",
- XkbAtomText(NULL, expr->value.field.element, XkbMessage),
- XkbAtomText(NULL, expr->value.field.field, XkbMessage));
- return ok;
- case ExprArrayRef:
- bogus = "array reference";
- case ExprActionDecl:
- if (bogus == NULL)
- bogus = "function use";
- ERROR1("Unexpected %s in mask expression\n", bogus);
- ACTION("Expression ignored\n");
- return False;
- case OpAdd:
- case OpSubtract:
- case OpMultiply:
- case OpDivide:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
- if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) &&
- ExprResolveMask(right, &rightRtrn, lookup, lookupPriv))
- {
- switch (expr->op)
- {
- case OpAdd:
- val_rtrn->ival = leftRtrn.ival | rightRtrn.ival;
- break;
- case OpSubtract:
- val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival);
- break;
- case OpMultiply:
- case OpDivide:
- ERROR1("Cannot %s masks\n",
- expr->op == OpDivide ? "divide" : "multiply");
- ACTION("Illegal operation ignored\n");
- return False;
- }
- return True;
- }
- return False;
- case OpAssign:
- WSGO("Assignment operator not implemented yet\n");
- break;
- case OpInvert:
- left = expr->value.child;
- if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
- {
- val_rtrn->ival = ~leftRtrn.ival;
- return True;
- }
- return False;
- case OpUnaryPlus:
- case OpNegate:
- case OpNot:
- left = expr->value.child;
- if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv))
- {
- ERROR1("The %s operator cannot be used with a mask\n",
- (expr->op == OpNegate ? "-" : "!"));
- }
- return False;
- default:
- WSGO1("Unknown operator %d in ResolveMask\n", expr->op);
- break;
- }
- return False;
-}
-
-int
-ExprResolveKeySym(ExprDef * expr,
- ExprResult * val_rtrn,
- IdentLookupFunc lookup, XPointer lookupPriv)
-{
- int ok = 0;
- KeySym sym;
-
- if (expr->op == ExprIdent)
- {
- char *str;
- str = XkbAtomGetString(NULL, expr->value.str);
- if ((str != NULL) && ((sym = XStringToKeysym(str)) != NoSymbol))
- {
- val_rtrn->uval = sym;
- return True;
- }
- }
- ok = ExprResolveInteger(expr, val_rtrn, lookup, lookupPriv);
- if ((ok) && (val_rtrn->uval < 10))
- val_rtrn->uval += '0';
- return ok;
-}
+/************************************************************ + 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 <ctype.h> + +/***====================================================================***/ + +char * +exprOpText(unsigned type) +{ + static char buf[32]; + + switch (type) + { + case ExprValue: + strcpy(buf, "literal"); + break; + case ExprIdent: + strcpy(buf, "identifier"); + break; + case ExprActionDecl: + strcpy(buf, "action declaration"); + break; + case ExprFieldRef: + strcpy(buf, "field reference"); + break; + case ExprArrayRef: + strcpy(buf, "array reference"); + break; + case ExprKeysymList: + strcpy(buf, "list of keysyms"); + break; + case ExprActionList: + strcpy(buf, "list of actions"); + break; + case OpAdd: + strcpy(buf, "addition"); + break; + case OpSubtract: + strcpy(buf, "subtraction"); + break; + case OpMultiply: + strcpy(buf, "multiplication"); + break; + case OpDivide: + strcpy(buf, "division"); + break; + case OpAssign: + strcpy(buf, "assignment"); + break; + case OpNot: + strcpy(buf, "logical not"); + break; + case OpNegate: + strcpy(buf, "arithmetic negation"); + break; + case OpInvert: + strcpy(buf, "bitwise inversion"); + break; + case OpUnaryPlus: + strcpy(buf, "plus sign"); + break; + default: + snprintf(buf, sizeof(buf), "illegal(%d)", type); + break; + } + return buf; +} + +char * +exprTypeText(unsigned type) +{ + static char buf[20]; + + switch (type) + { + case TypeUnknown: + strcpy(buf, "unknown"); + break; + case TypeBoolean: + strcpy(buf, "boolean"); + break; + case TypeInt: + strcpy(buf, "int"); + break; + case TypeString: + strcpy(buf, "string"); + break; + case TypeAction: + strcpy(buf, "action"); + break; + case TypeKeyName: + strcpy(buf, "keyname"); + break; + default: + snprintf(buf, sizeof(buf), "illegal(%d)", type); + break; + } + return buf; +} + +int +ExprResolveLhs(ExprDef * expr, + ExprResult * elem_rtrn, + ExprResult * field_rtrn, ExprDef ** index_rtrn) +{ + switch (expr->op) + { + case ExprIdent: + elem_rtrn->str = NULL; + field_rtrn->str = XkbAtomGetString(NULL, expr->value.str); + *index_rtrn = NULL; + return True; + case ExprFieldRef: + elem_rtrn->str = XkbAtomGetString(NULL, expr->value.field.element); + field_rtrn->str = XkbAtomGetString(NULL, expr->value.field.field); + *index_rtrn = NULL; + return True; + case ExprArrayRef: + elem_rtrn->str = XkbAtomGetString(NULL, expr->value.array.element); + field_rtrn->str = XkbAtomGetString(NULL, expr->value.array.field); + *index_rtrn = expr->value.array.entry; + return True; + } + WSGO1("Unexpected operator %d in ResolveLhs\n", expr->op); + return False; +} + +Bool +SimpleLookup(XPointer priv, + Atom elem, Atom field, unsigned type, ExprResult * val_rtrn) +{ + LookupEntry *entry; + register char *str; + + if ((priv == NULL) || + (field == None) || (elem != None) || + ((type != TypeInt) && (type != TypeFloat))) + { + return False; + } + str = XkbAtomGetString(NULL, field); + for (entry = (LookupEntry *) priv; + (entry != NULL) && (entry->name != NULL); entry++) + { + if (uStrCaseCmp(str, entry->name) == 0) + { + val_rtrn->uval = entry->result; + if (type == TypeFloat) + val_rtrn->uval *= XkbGeomPtsPerMM; + return True; + } + } + return False; +} + +Bool +RadioLookup(XPointer priv, + Atom elem, Atom field, unsigned type, ExprResult * val_rtrn) +{ + register char *str; + int rg; + + if ((field == None) || (elem != None) || (type != TypeInt)) + return False; + str = XkbAtomGetString(NULL, field); + if (str) + { + if (uStrCasePrefix("group", str)) + str += strlen("group"); + else if (uStrCasePrefix("radiogroup", str)) + str += strlen("radiogroup"); + else if (uStrCasePrefix("rg", str)) + str += strlen("rg"); + else if (!isdigit(str[0])) + str = NULL; + } + if ((!str) || (sscanf(str, "%i", &rg) < 1) || (rg < 1) + || (rg > XkbMaxRadioGroups)) + return False; + val_rtrn->uval = rg; + return True; +} + +int +TableLookup(XPointer priv, + Atom elem, Atom field, unsigned type, ExprResult * val_rtrn) +{ + LookupTable *tbl = (LookupTable *) priv; + register char *str; + + if ((priv == NULL) || (field == None) || (type != TypeInt)) + return False; + str = XkbAtomGetString(NULL, elem); + while (tbl) + { + if (((str == NULL) && (tbl->element == NULL)) || + ((str != NULL) && (tbl->element != NULL) && + (uStrCaseCmp(str, tbl->element) == 0))) + { + break; + } + tbl = tbl->nextElement; + } + if (tbl == NULL) /* didn't find a matching element */ + return False; + priv = (XPointer) tbl->entries; + return SimpleLookup(priv, (Atom) None, field, type, val_rtrn); +} + +static LookupEntry modIndexNames[] = { + {"shift", ShiftMapIndex}, + {"control", ControlMapIndex}, + {"lock", LockMapIndex}, + {"mod1", Mod1MapIndex}, + {"mod2", Mod2MapIndex}, + {"mod3", Mod3MapIndex}, + {"mod4", Mod4MapIndex}, + {"mod5", Mod5MapIndex}, + {"none", XkbNoModifier}, + {NULL, 0} +}; + +int +LookupModIndex(XPointer priv, + Atom elem, Atom field, unsigned type, ExprResult * val_rtrn) +{ + return SimpleLookup((XPointer) modIndexNames, elem, field, type, + val_rtrn); +} + +int +LookupModMask(XPointer priv, + Atom elem, Atom field, unsigned type, ExprResult * val_rtrn) +{ + char *str; + + if ((elem != None) || (type != TypeInt)) + return False; + str = XkbAtomGetString(NULL, field); + if (str == NULL) + return False; + if (uStrCaseCmp(str, "all") == 0) + val_rtrn->uval = 0xff; + else if (uStrCaseCmp(str, "none") == 0) + val_rtrn->uval = 0; + else if (LookupModIndex(priv, elem, field, type, val_rtrn)) + val_rtrn->uval = (1 << val_rtrn->uval); + else if (priv != NULL) + { + LookupPriv *lpriv = (LookupPriv *) priv; + if ((lpriv->chain == NULL) || + (!(*lpriv->chain) (lpriv->chainPriv, elem, field, type, + val_rtrn))) + return False; + } + else + return False; + return True; +} + +int +ExprResolveModIndex(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + char *bogus = NULL; + + switch (expr->op) + { + case ExprValue: + if (expr->type != TypeInt) + { + ERROR1 + ("Found constant of type %s where a modifier mask was expected\n", + exprTypeText(expr->type)); + return False; + } + else if ((expr->value.ival >= XkbNumModifiers) + || (expr->value.ival < 0)) + { + ERROR2("Illegal modifier index (%d, must be 0..%d)\n", + expr->value.ival, XkbNumModifiers - 1); + return False; + } + val_rtrn->ival = expr->value.ival; + return True; + case ExprIdent: + if (LookupModIndex(lookupPriv, (Atom) None, expr->value.str, + (unsigned) TypeInt, val_rtrn)) + { + return True; + } + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeInt, val_rtrn); + } + if (!ok) + ERROR1("Cannot determine modifier index for \"%s\"\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + break; + case ExprFieldRef: + bogus = "field reference"; + break; + case ExprArrayRef: + bogus = "array reference"; + break; + case ExprActionDecl: + bogus = "function"; + break; + case OpAdd: + case OpSubtract: + case OpMultiply: + case OpDivide: + case OpInvert: + case OpNegate: + case OpNot: + case OpUnaryPlus: + bogus = "arithmetic operations"; + break; + case OpAssign: + bogus = "assignment"; + break; + default: + WSGO1("Unknown operator %d in ResolveModIndex\n", expr->op); + return False; + } + if (bogus) + { + ERROR1("Modifier index must be a name or number, %s ignored\n", + bogus); + return False; + } + return ok; +} + +int +ExprResolveModMask(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + LookupPriv priv; + + priv.priv = NULL; + priv.chain = lookup; + priv.chainPriv = lookupPriv; + return ExprResolveMask(expr, val_rtrn, LookupModMask, (XPointer) & priv); +} + +int +ExprResolveBoolean(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + char *bogus = NULL; + + switch (expr->op) + { + case ExprValue: + if (expr->type != TypeBoolean) + { + ERROR1 + ("Found constant of type %s where boolean was expected\n", + exprTypeText(expr->type)); + return False; + } + val_rtrn->ival = expr->value.ival; + return True; + case ExprIdent: + bogus = XkbAtomGetString(NULL, expr->value.str); + if (bogus) + { + if ((uStrCaseCmp(bogus, "true") == 0) || + (uStrCaseCmp(bogus, "yes") == 0) || + (uStrCaseCmp(bogus, "on") == 0)) + { + val_rtrn->uval = 1; + return True; + } + else if ((uStrCaseCmp(bogus, "false") == 0) || + (uStrCaseCmp(bogus, "no") == 0) || + (uStrCaseCmp(bogus, "off") == 0)) + { + val_rtrn->uval = 0; + return True; + } + } + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeBoolean, val_rtrn); + } + if (!ok) + ERROR1("Identifier \"%s\" of type int is unknown\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeBoolean, val_rtrn); + } + if (!ok) + ERROR2("Default \"%s.%s\" of type boolean is unknown\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case OpInvert: + case OpNot: + ok = ExprResolveBoolean(expr, val_rtrn, lookup, lookupPriv); + if (ok) + val_rtrn->uval = !val_rtrn->uval; + return ok; + case OpAdd: + if (bogus == NULL) + bogus = "Addition"; + case OpSubtract: + if (bogus == NULL) + bogus = "Subtraction"; + case OpMultiply: + if (bogus == NULL) + bogus = "Multiplication"; + case OpDivide: + if (bogus == NULL) + bogus = "Division"; + case OpAssign: + if (bogus == NULL) + bogus = "Assignment"; + case OpNegate: + if (bogus == NULL) + bogus = "Negation"; + ERROR1("%s of boolean values not permitted\n", bogus); + break; + case OpUnaryPlus: + ERROR("Unary \"+\" operator not permitted for boolean values\n"); + break; + default: + WSGO1("Unknown operator %d in ResolveBoolean\n", expr->op); + break; + } + return False; +} + +int +ExprResolveFloat(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + ExprResult leftRtrn, rightRtrn; + ExprDef *left, *right; + + switch (expr->op) + { + case ExprValue: + if (expr->type == TypeString) + { + register char *str; + str = XkbAtomGetString(NULL, expr->value.str); + if ((str != NULL) && (strlen(str) == 1)) + { + val_rtrn->uval = str[0] * XkbGeomPtsPerMM; + return True; + } + } + if ((expr->type != TypeInt) && (expr->type != TypeFloat)) + { + ERROR1("Found constant of type %s, expected a number\n", + exprTypeText(expr->type)); + return False; + } + val_rtrn->ival = expr->value.ival; + if (expr->type == TypeInt) + val_rtrn->ival *= XkbGeomPtsPerMM; + return True; + case ExprIdent: + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeFloat, val_rtrn); + } + if (!ok) + ERROR1("Numeric identifier \"%s\" unknown\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeFloat, val_rtrn); + } + if (!ok) + ERROR2("Numeric default \"%s.%s\" unknown\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case OpAdd: + case OpSubtract: + case OpMultiply: + case OpDivide: + left = expr->value.binary.left; + right = expr->value.binary.right; + if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv) && + ExprResolveFloat(right, &rightRtrn, lookup, lookupPriv)) + { + switch (expr->op) + { + case OpAdd: + val_rtrn->ival = leftRtrn.ival + rightRtrn.ival; + break; + case OpSubtract: + val_rtrn->ival = leftRtrn.ival - rightRtrn.ival; + break; + case OpMultiply: + val_rtrn->ival = leftRtrn.ival * rightRtrn.ival; + break; + case OpDivide: + val_rtrn->ival = leftRtrn.ival / rightRtrn.ival; + break; + } + return True; + } + return False; + case OpAssign: + WSGO("Assignment operator not implemented yet\n"); + break; + case OpNot: + left = expr->value.child; + if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The ! operator cannot be applied to a number\n"); + } + return False; + case OpInvert: + case OpNegate: + left = expr->value.child; + if (ExprResolveFloat(left, &leftRtrn, lookup, lookupPriv)) + { + if (expr->op == OpNegate) + val_rtrn->ival = -leftRtrn.ival; + else + val_rtrn->ival = ~leftRtrn.ival; + return True; + } + return False; + case OpUnaryPlus: + left = expr->value.child; + return ExprResolveFloat(left, val_rtrn, lookup, lookupPriv); + default: + WSGO1("Unknown operator %d in ResolveFloat\n", expr->op); + break; + } + return False; +} + +int +ExprResolveInteger(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + ExprResult leftRtrn, rightRtrn; + ExprDef *left, *right; + + switch (expr->op) + { + case ExprValue: + if (expr->type == TypeString) + { + register char *str; + str = XkbAtomGetString(NULL, expr->value.str); + if (str != NULL) + switch (strlen(str)) + { + case 0: + val_rtrn->uval = 0; + return True; + case 1: + val_rtrn->uval = str[0]; + return True; + default: + break; + } + } + if ((expr->type != TypeInt) && (expr->type != TypeFloat)) + { + ERROR1 + ("Found constant of type %s where an int was expected\n", + exprTypeText(expr->type)); + return False; + } + val_rtrn->ival = expr->value.ival; + if (expr->type == TypeFloat) + val_rtrn->ival /= XkbGeomPtsPerMM; + return True; + case ExprIdent: + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeInt, val_rtrn); + } + if (!ok) + ERROR1("Identifier \"%s\" of type int is unknown\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeInt, val_rtrn); + } + if (!ok) + ERROR2("Default \"%s.%s\" of type int is unknown\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case OpAdd: + case OpSubtract: + case OpMultiply: + case OpDivide: + left = expr->value.binary.left; + right = expr->value.binary.right; + if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv) && + ExprResolveInteger(right, &rightRtrn, lookup, lookupPriv)) + { + switch (expr->op) + { + case OpAdd: + val_rtrn->ival = leftRtrn.ival + rightRtrn.ival; + break; + case OpSubtract: + val_rtrn->ival = leftRtrn.ival - rightRtrn.ival; + break; + case OpMultiply: + val_rtrn->ival = leftRtrn.ival * rightRtrn.ival; + break; + case OpDivide: + val_rtrn->ival = leftRtrn.ival / rightRtrn.ival; + break; + } + return True; + } + return False; + case OpAssign: + WSGO("Assignment operator not implemented yet\n"); + break; + case OpNot: + left = expr->value.child; + if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The ! operator cannot be applied to an integer\n"); + } + return False; + case OpInvert: + case OpNegate: + left = expr->value.child; + if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv)) + { + if (expr->op == OpNegate) + val_rtrn->ival = -leftRtrn.ival; + else + val_rtrn->ival = ~leftRtrn.ival; + return True; + } + return False; + case OpUnaryPlus: + left = expr->value.child; + return ExprResolveInteger(left, val_rtrn, lookup, lookupPriv); + default: + WSGO1("Unknown operator %d in ResolveInteger\n", expr->op); + break; + } + return False; +} + +int +ExprResolveString(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + ExprResult leftRtrn, rightRtrn; + ExprDef *left; + ExprDef *right; + char *bogus = NULL; + + switch (expr->op) + { + case ExprValue: + if (expr->type != TypeString) + { + ERROR1("Found constant of type %s, expected a string\n", + exprTypeText(expr->type)); + return False; + } + val_rtrn->str = XkbAtomGetString(NULL, expr->value.str); + if (val_rtrn->str == NULL) + { + static char *empty = ""; + val_rtrn->str = empty; + } + return True; + case ExprIdent: + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeString, val_rtrn); + } + if (!ok) + ERROR1("Identifier \"%s\" of type string not found\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeString, val_rtrn); + } + if (!ok) + ERROR2("Default \"%s.%s\" of type string not found\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case OpAdd: + left = expr->value.binary.left; + right = expr->value.binary.right; + if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv) && + ExprResolveString(right, &rightRtrn, lookup, lookupPriv)) + { + int len; + char *new; + len = strlen(leftRtrn.str) + strlen(rightRtrn.str) + 1; + new = (char *) uAlloc(len); + if (new) + { + sprintf(new, "%s%s", leftRtrn.str, rightRtrn.str); + val_rtrn->str = new; + return True; + } + } + return False; + case OpSubtract: + if (bogus == NULL) + bogus = "Subtraction"; + case OpMultiply: + if (bogus == NULL) + bogus = "Multiplication"; + case OpDivide: + if (bogus == NULL) + bogus = "Division"; + case OpAssign: + if (bogus == NULL) + bogus = "Assignment"; + case OpNegate: + if (bogus == NULL) + bogus = "Negation"; + case OpInvert: + if (bogus == NULL) + bogus = "Bitwise complement"; + ERROR1("%s of string values not permitted\n", bogus); + return False; + case OpNot: + left = expr->value.child; + if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The ! operator cannot be applied to a string\n"); + } + return False; + case OpUnaryPlus: + left = expr->value.child; + if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The + operator cannot be applied to a string\n"); + } + return False; + default: + WSGO1("Unknown operator %d in ResolveString\n", expr->op); + break; + } + return False; +} + +int +ExprResolveKeyName(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + ExprDef *left; + ExprResult leftRtrn; + char *bogus = NULL; + + switch (expr->op) + { + case ExprValue: + if (expr->type != TypeKeyName) + { + ERROR1("Found constant of type %s, expected a key name\n", + exprTypeText(expr->type)); + return False; + } + memcpy(val_rtrn->keyName.name, expr->value.keyName, XkbKeyNameLength); + return True; + case ExprIdent: + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeString, val_rtrn); + } + if (!ok) + ERROR1("Identifier \"%s\" of type string not found\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeString, val_rtrn); + } + if (!ok) + ERROR2("Default \"%s.%s\" of type key name not found\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case OpAdd: + if (bogus == NULL) + bogus = "Addition"; + case OpSubtract: + if (bogus == NULL) + bogus = "Subtraction"; + case OpMultiply: + if (bogus == NULL) + bogus = "Multiplication"; + case OpDivide: + if (bogus == NULL) + bogus = "Division"; + case OpAssign: + if (bogus == NULL) + bogus = "Assignment"; + case OpNegate: + if (bogus == NULL) + bogus = "Negation"; + case OpInvert: + if (bogus == NULL) + bogus = "Bitwise complement"; + ERROR1("%s of key name values not permitted\n", bogus); + return False; + case OpNot: + left = expr->value.binary.left; + if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The ! operator cannot be applied to a key name\n"); + } + return False; + case OpUnaryPlus: + left = expr->value.binary.left; + if (ExprResolveString(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR("The + operator cannot be applied to a key name\n"); + } + return False; + default: + WSGO1("Unknown operator %d in ResolveKeyName\n", expr->op); + break; + } + return False; +} + +/***====================================================================***/ + +int +ExprResolveEnum(ExprDef * expr, ExprResult * val_rtrn, LookupEntry * values) +{ + if (expr->op != ExprIdent) + { + ERROR1("Found a %s where an enumerated value was expected\n", + exprOpText(expr->op)); + return False; + } + if (!SimpleLookup((XPointer) values, (Atom) None, expr->value.str, + (unsigned) TypeInt, val_rtrn)) + { + int nOut = 0; + ERROR1("Illegal identifier %s (expected one of: ", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + while (values && values->name) + { + if (nOut != 0) + INFO1(", %s", values->name); + else + INFO1("%s", values->name); + values++; + nOut++; + } + INFO(")\n"); + return False; + } + return True; +} + +int +ExprResolveMask(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + ExprResult leftRtrn, rightRtrn; + ExprDef *left, *right; + char *bogus = NULL; + + switch (expr->op) + { + case ExprValue: + if (expr->type != TypeInt) + { + ERROR1 + ("Found constant of type %s where a mask was expected\n", + exprTypeText(expr->type)); + return False; + } + val_rtrn->ival = expr->value.ival; + return True; + case ExprIdent: + if (lookup) + { + ok = (*lookup) (lookupPriv, + None, expr->value.str, TypeInt, val_rtrn); + } + if (!ok) + ERROR1("Identifier \"%s\" of type int is unknown\n", + XkbAtomText(NULL, expr->value.str, XkbMessage)); + return ok; + case ExprFieldRef: + if (lookup) + { + ok = (*lookup) (lookupPriv, + expr->value.field.element, + expr->value.field.field, TypeInt, val_rtrn); + } + if (!ok) + ERROR2("Default \"%s.%s\" of type int is unknown\n", + XkbAtomText(NULL, expr->value.field.element, XkbMessage), + XkbAtomText(NULL, expr->value.field.field, XkbMessage)); + return ok; + case ExprArrayRef: + bogus = "array reference"; + case ExprActionDecl: + if (bogus == NULL) + bogus = "function use"; + ERROR1("Unexpected %s in mask expression\n", bogus); + ACTION("Expression ignored\n"); + return False; + case OpAdd: + case OpSubtract: + case OpMultiply: + case OpDivide: + left = expr->value.binary.left; + right = expr->value.binary.right; + if (ExprResolveMask(left, &leftRtrn, lookup, lookupPriv) && + ExprResolveMask(right, &rightRtrn, lookup, lookupPriv)) + { + switch (expr->op) + { + case OpAdd: + val_rtrn->ival = leftRtrn.ival | rightRtrn.ival; + break; + case OpSubtract: + val_rtrn->ival = leftRtrn.ival & (~rightRtrn.ival); + break; + case OpMultiply: + case OpDivide: + ERROR1("Cannot %s masks\n", + expr->op == OpDivide ? "divide" : "multiply"); + ACTION("Illegal operation ignored\n"); + return False; + } + return True; + } + return False; + case OpAssign: + WSGO("Assignment operator not implemented yet\n"); + break; + case OpInvert: + left = expr->value.child; + if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv)) + { + val_rtrn->ival = ~leftRtrn.ival; + return True; + } + return False; + case OpUnaryPlus: + case OpNegate: + case OpNot: + left = expr->value.child; + if (ExprResolveInteger(left, &leftRtrn, lookup, lookupPriv)) + { + ERROR1("The %s operator cannot be used with a mask\n", + (expr->op == OpNegate ? "-" : "!")); + } + return False; + default: + WSGO1("Unknown operator %d in ResolveMask\n", expr->op); + break; + } + return False; +} + +int +ExprResolveKeySym(ExprDef * expr, + ExprResult * val_rtrn, + IdentLookupFunc lookup, XPointer lookupPriv) +{ + int ok = 0; + KeySym sym; + + if (expr->op == ExprIdent) + { + char *str; + str = XkbAtomGetString(NULL, expr->value.str); + if ((str != NULL) && ((sym = XStringToKeysym(str)) != NoSymbol)) + { + val_rtrn->uval = sym; + return True; + } + } + ok = ExprResolveInteger(expr, val_rtrn, lookup, lookupPriv); + if ((ok) && (val_rtrn->uval < 10)) + val_rtrn->uval += '0'; + return ok; +} diff --git a/xkbcomp/expr.h b/xkbcomp/expr.h index bd7e82248..02519f941 100644 --- a/xkbcomp/expr.h +++ b/xkbcomp/expr.h @@ -1,172 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/indicators.c b/xkbcomp/indicators.c index 63dc18b7b..d4a362fb8 100644 --- a/xkbcomp/indicators.c +++ b/xkbcomp/indicators.c @@ -1,575 +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;
-}
+/************************************************************ + 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; +} diff --git a/xkbcomp/indicators.h b/xkbcomp/indicators.h index 9c72f70d5..35ae38a4c 100644 --- a/xkbcomp/indicators.h +++ b/xkbcomp/indicators.h @@ -1,88 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/keycodes.c b/xkbcomp/keycodes.c index 3517586c7..13579ec1a 100644 --- a/xkbcomp/keycodes.c +++ b/xkbcomp/keycodes.c @@ -1,894 +1,894 @@ -/************************************************************
- 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;
-
- 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;
- ACTION2("Using %s instead of %s\n",
- (old->virtual ? "virtual" : "real"),
- (old->virtual ? "real" : "virtual"));
- }
- else
- {
- ACTION("Identical definitions ignored\n");
- }
- return True;
- }
- else
- {
- if (replace)
- ACTION2("Ignoring %d, using %d\n", old->ndx, new->ndx);
- else
- ACTION2("Using %d, ignoring %d\n", 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;
-}
+/************************************************************ + 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; + + 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; + ACTION2("Using %s instead of %s\n", + (old->virtual ? "virtual" : "real"), + (old->virtual ? "real" : "virtual")); + } + else + { + ACTION("Identical definitions ignored\n"); + } + return True; + } + else + { + if (replace) + ACTION2("Ignoring %d, using %d\n", old->ndx, new->ndx); + else + ACTION2("Using %d, ignoring %d\n", 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; +} diff --git a/xkbcomp/keycodes.h b/xkbcomp/keycodes.h index b7f5b9989..11f4460fe 100644 --- a/xkbcomp/keycodes.h +++ b/xkbcomp/keycodes.h @@ -1,40 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/keymap.c b/xkbcomp/keymap.c index 2c90f515d..a419d8c42 100644 --- a/xkbcomp/keymap.c +++ b/xkbcomp/keymap.c @@ -1,183 +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;
-}
+/************************************************************ + 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; +} diff --git a/xkbcomp/keytypes.c b/xkbcomp/keytypes.c index d0d5302f9..da55d755d 100644 --- a/xkbcomp/keytypes.c +++ b/xkbcomp/keytypes.c @@ -1,1293 +1,1293 @@ -/************************************************************
- 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"
-
-typedef struct _PreserveInfo
-{
- CommonInfo defs;
- short matchingMapIndex;
- unsigned char indexMods;
- unsigned char preMods;
- unsigned short indexVMods;
- unsigned short preVMods;
-} PreserveInfo;
-
-#define _KT_Name (1<<0)
-#define _KT_Mask (1<<1)
-#define _KT_Map (1<<2)
-#define _KT_Preserve (1<<3)
-#define _KT_LevelNames (1<<4)
-
-typedef struct _KeyTypeInfo
-{
- CommonInfo defs;
- Display *dpy;
- Atom name;
- int fileID;
- unsigned mask;
- unsigned vmask;
- Bool groupInfo;
- int numLevels;
- int nEntries;
- int szEntries;
- XkbKTMapEntryPtr entries;
- PreserveInfo *preserve;
- int szNames;
- Atom *lvlNames;
-} KeyTypeInfo;
-
-typedef struct _KeyTypesInfo
-{
- Display *dpy;
- char *name;
- int errorCount;
- int fileID;
- unsigned stdPresent;
- int nTypes;
- KeyTypeInfo *types;
- KeyTypeInfo dflt;
- VModInfo vmods;
-} KeyTypesInfo;
-
-Atom tok_ONE_LEVEL;
-Atom tok_TWO_LEVEL;
-Atom tok_ALPHABETIC;
-Atom tok_KEYPAD;
-
-/***====================================================================***/
-
-#define ReportTypeShouldBeArray(t,f) \
- ReportShouldBeArray("key type",(f),TypeTxt(t))
-#define ReportTypeBadType(t,f,w) \
- ReportBadType("key type",(f),TypeTxt(t),(w))
-
-/***====================================================================***/
-
-extern Bool AddMapEntry(XkbDescPtr /* xkb */ ,
- KeyTypeInfo * /* type */ ,
- XkbKTMapEntryPtr /* new */ ,
- Bool /* clobber */ ,
- Bool /* report */
- );
-
-extern Bool AddPreserve(XkbDescPtr /* xkb */ ,
- KeyTypeInfo * /* type */ ,
- PreserveInfo * /* new */ ,
- Bool /* clobber */ ,
- Bool /* report */
- );
-
-extern Bool AddLevelName(KeyTypeInfo * /* type */ ,
- unsigned /* level */ ,
- Atom /* name */ ,
- Bool /* clobber */ ,
- Bool /* report */
- );
-
-#define MapEntryTxt(t,x,e) \
- XkbVModMaskText((t)->dpy,(x),(e)->mods.real_mods,(e)->mods.vmods,XkbMessage)
-#define PreserveIndexTxt(t,x,p) \
- XkbVModMaskText((t)->dpy,(x),(p)->indexMods,(p)->indexVMods,XkbMessage)
-#define PreserveTxt(t,x,p) \
- XkbVModMaskText((t)->dpy,(x),(p)->preMods,(p)->preVMods,XkbMessage)
-#define TypeTxt(t) XkbAtomText((t)->dpy,(t)->name,XkbMessage)
-#define TypeMaskTxt(t,x) \
- XkbVModMaskText((t)->dpy,(x),(t)->mask,(t)->vmask,XkbMessage)
-
-/***====================================================================***/
-
-static void
-InitKeyTypesInfo(KeyTypesInfo * info, XkbDescPtr xkb, KeyTypesInfo * from)
-{
- tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False);
- tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False);
- tok_ALPHABETIC = XkbInternAtom(NULL, "ALPHABETIC", False);
- tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False);
- info->dpy = NULL;
- info->name = uStringDup("default");
- info->errorCount = 0;
- info->stdPresent = 0;
- info->nTypes = 0;
- info->types = NULL;
- info->dflt.defs.defined = 0;
- info->dflt.defs.fileID = 0;
- info->dflt.defs.merge = MergeOverride;
- info->dflt.defs.next = NULL;
- info->dflt.name = None;
- info->dflt.mask = 0;
- info->dflt.vmask = 0;
- info->dflt.groupInfo = False;
- info->dflt.numLevels = 1;
- info->dflt.nEntries = info->dflt.szEntries = 0;
- info->dflt.entries = NULL;
- info->dflt.szNames = 0;
- info->dflt.lvlNames = NULL;
- info->dflt.preserve = NULL;
- InitVModInfo(&info->vmods, xkb);
- if (from != NULL)
- {
- info->dpy = from->dpy;
- info->dflt = from->dflt;
- if (from->dflt.entries)
- {
- info->dflt.entries = uTypedCalloc(from->dflt.szEntries,
- XkbKTMapEntryRec);
- if (info->dflt.entries)
- {
- unsigned sz = from->dflt.nEntries * sizeof(XkbKTMapEntryRec);
- memcpy(info->dflt.entries, from->dflt.entries, sz);
- }
- }
- if (from->dflt.lvlNames)
- {
- info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, Atom);
- if (info->dflt.lvlNames)
- {
- register unsigned sz = from->dflt.szNames * sizeof(Atom);
- memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz);
- }
- }
- if (from->dflt.preserve)
- {
- PreserveInfo *old, *new, *last;
- last = NULL;
- old = from->dflt.preserve;
- for (; old; old = (PreserveInfo *) old->defs.next)
- {
- new = uTypedAlloc(PreserveInfo);
- if (!new)
- return;
- *new = *old;
- new->defs.next = NULL;
- if (last)
- last->defs.next = (CommonInfo *) new;
- else
- info->dflt.preserve = new;
- last = new;
- }
- }
- }
- return;
-}
-
-static void
-FreeKeyTypeInfo(KeyTypeInfo * type)
-{
- if (type->entries != NULL)
- {
- uFree(type->entries);
- type->entries = NULL;
- }
- if (type->lvlNames != NULL)
- {
- uFree(type->lvlNames);
- type->lvlNames = NULL;
- }
- if (type->preserve != NULL)
- {
- ClearCommonInfo(&type->preserve->defs);
- type->preserve = NULL;
- }
- return;
-}
-
-static void
-FreeKeyTypesInfo(KeyTypesInfo * info)
-{
- info->dpy = NULL;
- if (info->name)
- uFree(info->name);
- info->name = NULL;
- if (info->types)
- {
- register KeyTypeInfo *type;
- for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next)
- {
- FreeKeyTypeInfo(type);
- }
- info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs);
- }
- FreeKeyTypeInfo(&info->dflt);
- return;
-}
-
-static KeyTypeInfo *
-NextKeyType(KeyTypesInfo * info)
-{
- KeyTypeInfo *type;
-
- type = uTypedAlloc(KeyTypeInfo);
- if (type != NULL)
- {
- bzero(type, sizeof(KeyTypeInfo));
- type->defs.fileID = info->fileID;
- type->dpy = info->dpy;
- info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs,
- (CommonInfo *) type);
- info->nTypes++;
- }
- return type;
-}
-
-static KeyTypeInfo *
-FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new)
-{
- KeyTypeInfo *old;
-
- for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next)
- {
- if (old->name == new->name)
- return old;
- }
- return NULL;
-}
-
-static Bool
-ReportTypeBadWidth(const char *type, int has, int needs)
-{
- ERROR3("Key type \"%s\" has %d levels, must have %d\n", type, has, needs);
- ACTION("Illegal type definition ignored\n");
- return False;
-}
-
-static Bool
-AddKeyType(XkbDescPtr xkb, KeyTypesInfo * info, KeyTypeInfo * new)
-{
- KeyTypeInfo *old;
-
- if (new->name == tok_ONE_LEVEL)
- {
- if (new->numLevels > 1)
- return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1);
- info->stdPresent |= XkbOneLevelMask;
- }
- else if (new->name == tok_TWO_LEVEL)
- {
- if (new->numLevels > 2)
- return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2);
- else if (new->numLevels < 2)
- new->numLevels = 2;
- info->stdPresent |= XkbTwoLevelMask;
- }
- else if (new->name == tok_ALPHABETIC)
- {
- if (new->numLevels > 2)
- return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2);
- else if (new->numLevels < 2)
- new->numLevels = 2;
- info->stdPresent |= XkbAlphabeticMask;
- }
- else if (new->name == tok_KEYPAD)
- {
- if (new->numLevels > 2)
- return ReportTypeBadWidth("KEYPAD", new->numLevels, 2);
- else if (new->numLevels < 2)
- new->numLevels = 2;
- info->stdPresent |= XkbKeypadMask;
- }
-
- old = FindMatchingKeyType(info, new);
- if (old != NULL)
- {
- Bool report;
- if ((new->defs.merge == MergeReplace)
- || (new->defs.merge == MergeOverride))
- {
- KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next;
- if (((old->defs.fileID == new->defs.fileID)
- && (warningLevel > 0)) || (warningLevel > 9))
- {
- WARN1("Multiple definitions of the %s key type\n",
- XkbAtomGetString(NULL, new->name));
- ACTION("Earlier definition ignored\n");
- }
- FreeKeyTypeInfo(old);
- *old = *new;
- new->szEntries = new->nEntries = 0;
- new->entries = NULL;
- new->preserve = NULL;
- new->lvlNames = NULL;
- old->defs.next = &next->defs;
- return True;
- }
- report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0);
- if (report)
- {
- WARN1("Multiple definitions of the %s key type\n",
- XkbAtomGetString(NULL, new->name));
- ACTION("Later definition ignored\n");
- }
- FreeKeyTypeInfo(new);
- return True;
- }
- old = NextKeyType(info);
- if (old == NULL)
- return False;
- *old = *new;
- old->defs.next = NULL;
- new->nEntries = new->szEntries = 0;
- new->entries = NULL;
- new->szNames = 0;
- new->lvlNames = NULL;
- new->preserve = NULL;
- return True;
-}
-
-/***====================================================================***/
-
-static void
-MergeIncludedKeyTypes(KeyTypesInfo * into,
- KeyTypesInfo * from, unsigned merge, XkbDescPtr xkb)
-{
- KeyTypeInfo *type;
-
- if (from->errorCount > 0)
- {
- into->errorCount += from->errorCount;
- return;
- }
- if (into->name == NULL)
- {
- into->name = from->name;
- from->name = NULL;
- }
- for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next)
- {
- if (merge != MergeDefault)
- type->defs.merge = merge;
- if (!AddKeyType(xkb, into, type))
- into->errorCount++;
- }
- into->stdPresent |= from->stdPresent;
- return;
-}
-
-typedef void (*FileHandler) (XkbFile * /* file */ ,
- XkbDescPtr /* xkb */ ,
- unsigned /* merge */ ,
- KeyTypesInfo * /* included */
- );
-
-static Bool
-HandleIncludeKeyTypes(IncludeStmt * stmt,
- XkbDescPtr xkb, KeyTypesInfo * info, FileHandler hndlr)
-{
- unsigned newMerge;
- XkbFile *rtrn;
- KeyTypesInfo included;
- Bool haveSelf;
-
- haveSelf = False;
- if ((stmt->file == NULL) && (stmt->map == NULL))
- {
- haveSelf = True;
- included = *info;
- bzero(info, sizeof(KeyTypesInfo));
- }
- else if (ProcessIncludeFile(stmt, XkmTypesIndex, &rtrn, &newMerge))
- {
- InitKeyTypesInfo(&included, xkb, info);
- included.fileID = included.dflt.defs.fileID = rtrn->id;
- included.dflt.defs.merge = newMerge;
-
- (*hndlr) (rtrn, xkb, newMerge, &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;
- KeyTypesInfo next_incl;
-
- for (next = stmt->next; next != NULL; next = next->next)
- {
- if ((next->file == NULL) && (next->map == NULL))
- {
- haveSelf = True;
- MergeIncludedKeyTypes(&included, info, next->merge, xkb);
- FreeKeyTypesInfo(info);
- }
- else if (ProcessIncludeFile(next, XkmTypesIndex, &rtrn, &op))
- {
- InitKeyTypesInfo(&next_incl, xkb, &included);
- next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
- next_incl.dflt.defs.merge = op;
- (*hndlr) (rtrn, xkb, op, &next_incl);
- MergeIncludedKeyTypes(&included, &next_incl, op, xkb);
- FreeKeyTypesInfo(&next_incl);
- }
- else
- {
- info->errorCount += 10;
- return False;
- }
- }
- }
- if (haveSelf)
- *info = included;
- else
- {
- MergeIncludedKeyTypes(info, &included, newMerge, xkb);
- FreeKeyTypesInfo(&included);
- }
- return (info->errorCount == 0);
-}
-
-/***====================================================================***/
-
-static XkbKTMapEntryPtr
-FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask)
-{
- register int i;
- XkbKTMapEntryPtr entry;
-
- for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++)
- {
- if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask))
- return entry;
- }
- return NULL;
-}
-
-static void
-DeleteLevel1MapEntries(KeyTypeInfo * type)
-{
- register int i, n;
-
- for (i = 0; i < type->nEntries; i++)
- {
- if (type->entries[i].level == 0)
- {
- for (n = i; n < type->nEntries - 1; n++)
- {
- type->entries[n] = type->entries[n + 1];
- }
- type->nEntries--;
- }
- }
- return;
-}
-
-/**
- * Return a pointer to the next free XkbKTMapEntry, reallocating space if
- * necessary.
- */
-static XkbKTMapEntryPtr
-NextMapEntry(KeyTypeInfo * type)
-{
- if (type->entries == NULL)
- {
- type->entries = uTypedCalloc(2, XkbKTMapEntryRec);
- if (type->entries == NULL)
- {
- ERROR1("Couldn't allocate map entries for %s\n", TypeTxt(type));
- ACTION("Map entries lost\n");
- return NULL;
- }
- type->szEntries = 2;
- type->nEntries = 0;
- }
- else if (type->nEntries >= type->szEntries)
- {
- type->szEntries *= 2;
- type->entries = uTypedRecalloc(type->entries,
- type->nEntries, type->szEntries,
- XkbKTMapEntryRec);
- if (type->entries == NULL)
- {
- ERROR1("Couldn't reallocate map entries for %s\n", TypeTxt(type));
- ACTION("Map entries lost\n");
- return NULL;
- }
- }
- return &type->entries[type->nEntries++];
-}
-
-Bool
-AddPreserve(XkbDescPtr xkb,
- KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report)
-{
- PreserveInfo *old;
-
- old = type->preserve;
- while (old != NULL)
- {
- if ((old->indexMods != new->indexMods) ||
- (old->indexVMods != new->indexVMods))
- {
- old = (PreserveInfo *) old->defs.next;
- continue;
- }
- if ((old->preMods == new->preMods)
- && (old->preVMods == new->preVMods))
- {
- if (warningLevel > 9)
- {
- WARN2("Identical definitions for preserve[%s] in %s\n",
- PreserveIndexTxt(type, xkb, old), TypeTxt(type));
- ACTION("Ignored\n");
- }
- return True;
- }
- if (report && (warningLevel > 0))
- {
- char *str;
- WARN2("Multiple definitions for preserve[%s] in %s\n",
- PreserveIndexTxt(type, xkb, old), TypeTxt(type));
-
- if (clobber)
- str = PreserveTxt(type, xkb, new);
- else
- str = PreserveTxt(type, xkb, old);
- ACTION1("Using %s, ", str);
- if (clobber)
- str = PreserveTxt(type, xkb, old);
- else
- str = PreserveTxt(type, xkb, new);
- INFO1("ignoring %s\n", str);
- }
- if (clobber)
- {
- old->preMods = new->preMods;
- old->preVMods = new->preVMods;
- }
- return True;
- }
- old = uTypedAlloc(PreserveInfo);
- if (!old)
- {
- WSGO1("Couldn't allocate preserve in %s\n", TypeTxt(type));
- ACTION1("Preserve[%s] lost\n", PreserveIndexTxt(type, xkb, old));
- return False;
- }
- *old = *new;
- old->matchingMapIndex = -1;
- type->preserve =
- (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs);
- return True;
-}
-
-/**
- * Add a new KTMapEntry to the given key type. If an entry with the same mods
- * already exists, the level is updated (if clobber is TRUE). Otherwise, a new
- * entry is created.
- *
- * @param clobber Overwrite existing entry.
- * @param report True if a warning is to be printed on.
- */
-Bool
-AddMapEntry(XkbDescPtr xkb,
- KeyTypeInfo * type,
- XkbKTMapEntryPtr new, Bool clobber, Bool report)
-{
- XkbKTMapEntryPtr old;
-
- if ((old =
- FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods)))
- {
- if (report && (old->level != new->level))
- {
- unsigned use, ignore;
- if (clobber)
- {
- use = new->level + 1;
- ignore = old->level + 1;
- }
- else
- {
- use = old->level + 1;
- ignore = new->level + 1;
- }
- WARN2("Multiple map entries for %s in %s\n",
- MapEntryTxt(type, xkb, new), TypeTxt(type));
- ACTION2("Using %d, ignoring %d\n", use, ignore);
- }
- else if (warningLevel > 9)
- {
- WARN3("Multiple occurences of map[%s]= %d in %s\n",
- MapEntryTxt(type, xkb, new), new->level + 1, TypeTxt(type));
- ACTION("Ignored\n");
- return True;
- }
- if (clobber)
- old->level = new->level;
- return True;
- }
- if ((old = NextMapEntry(type)) == NULL)
- return False; /* allocation failure, already reported */
- if (new->level >= type->numLevels)
- type->numLevels = new->level + 1;
- if (new->mods.vmods == 0)
- old->active = True;
- else
- old->active = False;
- old->mods.mask = new->mods.real_mods;
- old->mods.real_mods = new->mods.real_mods;
- old->mods.vmods = new->mods.vmods;
- old->level = new->level;
- return True;
-}
-
-static LookupEntry lnames[] = {
- {"level1", 1},
- {"level2", 2},
- {"level3", 3},
- {"level4", 4},
- {"level5", 5},
- {"level6", 6},
- {"level7", 7},
- {"level8", 8},
- {NULL, 0}
-};
-
-static Bool
-SetMapEntry(KeyTypeInfo * type,
- XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
-{
- ExprResult rtrn;
- XkbKTMapEntryRec entry;
-
- if (arrayNdx == NULL)
- return ReportTypeShouldBeArray(type, "map entry");
- if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb))
- return ReportTypeBadType(type, "map entry", "modifier mask");
- entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */
- entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */
- if ((entry.mods.real_mods & (~type->mask)) ||
- ((entry.mods.vmods & (~type->vmask)) != 0))
- {
- if (warningLevel > 0)
- {
- WARN1("Map entry for unused modifiers in %s\n", TypeTxt(type));
- ACTION1("Using %s instead of ",
- XkbVModMaskText(type->dpy, xkb,
- entry.mods.real_mods & type->mask,
- entry.mods.vmods & type->vmask,
- XkbMessage));
- INFO1("%s\n", MapEntryTxt(type, xkb, &entry));
- }
- entry.mods.real_mods &= type->mask;
- entry.mods.vmods &= type->vmask;
- }
- if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (XPointer) lnames))
- {
- ERROR("Level specifications in a key type must be integer\n");
- ACTION("Ignoring malformed level specification\n");
- return False;
- }
- if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
- {
- ERROR3("Shift level %d out of range (1..%d) in key type %s\n",
- XkbMaxShiftLevel + 1, rtrn.ival, TypeTxt(type));
- ACTION1("Ignoring illegal definition of map[%s]\n",
- MapEntryTxt(type, xkb, &entry));
- return False;
- }
- entry.level = rtrn.ival - 1;
- return AddMapEntry(xkb, type, &entry, True, True);
-}
-
-static Bool
-SetPreserve(KeyTypeInfo * type,
- XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value)
-{
- ExprResult rtrn;
- PreserveInfo new;
-
- if (arrayNdx == NULL)
- return ReportTypeShouldBeArray(type, "preserve entry");
- if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb))
- return ReportTypeBadType(type, "preserve entry", "modifier mask");
- new.defs = type->defs;
- new.defs.next = NULL;
- new.indexMods = rtrn.uval & 0xff;
- new.indexVMods = (rtrn.uval >> 8) & 0xffff;
- if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask)))
- {
- if (warningLevel > 0)
- {
- WARN1("Preserve for modifiers not used by the %s type\n",
- TypeTxt(type));
- ACTION1("Index %s converted to ",
- PreserveIndexTxt(type, xkb, &new));
- }
- new.indexMods &= type->mask;
- new.indexVMods &= type->vmask;
- if (warningLevel > 0)
- INFO1("%s\n", PreserveIndexTxt(type, xkb, &new));
- }
- if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
- {
- ERROR("Preserve value in a key type is not a modifier mask\n");
- ACTION2("Ignoring preserve[%s] in type %s\n",
- PreserveIndexTxt(type, xkb, &new), TypeTxt(type));
- return False;
- }
- new.preMods = rtrn.uval & 0xff;
- new.preVMods = (rtrn.uval >> 16) & 0xffff;
- if ((new.preMods & (~new.indexMods))
- || (new.preVMods && (~new.indexVMods)))
- {
- if (warningLevel > 0)
- {
- WARN2("Illegal value for preserve[%s] in type %s\n",
- PreserveTxt(type, xkb, &new), TypeTxt(type));
- ACTION1("Converted %s to ", PreserveIndexTxt(type, xkb, &new));
- }
- new.preMods &= new.indexMods;
- new.preVMods &= new.indexVMods;
- if (warningLevel > 0)
- {
- INFO1("%s\n", PreserveIndexTxt(type, xkb, &new));
- }
- }
- return AddPreserve(xkb, type, &new, True, True);
-}
-
-/***====================================================================***/
-
-Bool
-AddLevelName(KeyTypeInfo * type,
- unsigned level, Atom name, Bool clobber, Bool report)
-{
- if ((type->lvlNames == NULL) || (type->szNames <= level))
- {
- type->lvlNames =
- uTypedRecalloc(type->lvlNames, type->szNames, level + 1, Atom);
- if (type->lvlNames == NULL)
- {
- ERROR1("Couldn't allocate level names for type %s\n",
- TypeTxt(type));
- ACTION("Level names lost\n");
- type->szNames = 0;
- return False;
- }
- type->szNames = level + 1;
- }
- else if (type->lvlNames[level] == name)
- {
- if (warningLevel > 9)
- {
- WARN2("Duplicate names for level %d of key type %s\n",
- level + 1, TypeTxt(type));
- ACTION("Ignored\n");
- }
- return True;
- }
- else if (type->lvlNames[level] != None)
- {
- if (warningLevel > 0)
- {
- char *old, *new;
- old = XkbAtomText(type->dpy, type->lvlNames[level], XkbMessage);
- new = XkbAtomText(type->dpy, name, XkbMessage);
- WARN2("Multiple names for level %d of key type %s\n",
- level + 1, TypeTxt(type));
- if (clobber)
- ACTION2("Using %s, ignoring %s\n", new, old);
- else
- ACTION2("Using %s, ignoring %s\n", old, new);
- }
- if (!clobber)
- return True;
- }
- if (level >= type->numLevels)
- type->numLevels = level + 1;
- type->lvlNames[level] = name;
- return True;
-}
-
-static Bool
-SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value)
-{
- ExprResult rtrn;
- unsigned level;
-
- if (arrayNdx == NULL)
- return ReportTypeShouldBeArray(type, "level name");
- if (!ExprResolveInteger(arrayNdx, &rtrn, SimpleLookup, (XPointer) lnames))
- return ReportTypeBadType(type, "level name", "integer");
- if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1))
- {
- ERROR3("Level name %d out of range (1..%d) in key type %s\n",
- rtrn.ival,
- XkbMaxShiftLevel + 1,
- XkbAtomText(type->dpy, type->name, XkbMessage));
- ACTION("Ignoring illegal level name definition\n");
- return False;
- }
- level = rtrn.ival - 1;
- if (!ExprResolveString(value, &rtrn, NULL, NULL))
- {
- ERROR2("Non-string name for level %d in key type %s\n", level + 1,
- XkbAtomText(type->dpy, type->name, XkbMessage));
- ACTION("Ignoring illegal level name definition\n");
- return False;
- }
- return
- AddLevelName(type, level, XkbInternAtom(NULL, rtrn.str, False), True,
- True);
-}
-
-/***====================================================================***/
-
-/**
- * Parses the fields in a type "..." { } description.
- *
- * @param field The field to parse (e.g. modifiers, map, level_name)
- */
-static Bool
-SetKeyTypeField(KeyTypeInfo * type,
- XkbDescPtr xkb,
- char *field,
- ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info)
-{
- ExprResult tmp;
-
- if (uStrCaseCmp(field, "modifiers") == 0)
- {
- unsigned mods, vmods;
- if (arrayNdx != NULL)
- {
- WARN("The modifiers field of a key type is not an array\n");
- ACTION("Illegal array subscript ignored\n");
- }
- /* get modifier mask for current type */
- if (!ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb))
- {
- ERROR("Key type mask field must be a modifier mask\n");
- ACTION("Key type definition ignored\n");
- return False;
- }
- mods = tmp.uval & 0xff; /* core mods */
- vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */
- if (type->defs.defined & _KT_Mask)
- {
- WARN1("Multiple modifier mask definitions for key type %s\n",
- XkbAtomText(type->dpy, type->name, XkbMessage));
- ACTION1("Using %s, ", TypeMaskTxt(type, xkb));
- INFO1("ignoring %s\n", XkbVModMaskText(type->dpy, xkb, mods,
- vmods, XkbMessage));
- return False;
- }
- type->mask = mods;
- type->vmask = vmods;
- type->defs.defined |= _KT_Mask;
- return True;
- }
- else if (uStrCaseCmp(field, "map") == 0)
- {
- type->defs.defined |= _KT_Map;
- return SetMapEntry(type, xkb, arrayNdx, value);
- }
- else if (uStrCaseCmp(field, "preserve") == 0)
- {
- type->defs.defined |= _KT_Preserve;
- return SetPreserve(type, xkb, arrayNdx, value);
- }
- else if ((uStrCaseCmp(field, "levelname") == 0) ||
- (uStrCaseCmp(field, "level_name") == 0))
- {
- type->defs.defined |= _KT_LevelNames;
- return SetLevelName(type, arrayNdx, value);
- }
- ERROR2("Unknown field %s in key type %s\n", field, TypeTxt(type));
- ACTION("Definition ignored\n");
- return False;
-}
-
-static Bool
-HandleKeyTypeVar(VarDef * stmt, XkbDescPtr xkb, KeyTypesInfo * info)
-{
- ExprResult elem, field;
- ExprDef *arrayNdx;
-
- if (!ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx))
- return False; /* internal error, already reported */
- if (elem.str && (uStrCaseCmp(elem.str, "type") == 0))
- return SetKeyTypeField(&info->dflt, xkb, field.str, arrayNdx,
- stmt->value, info);
- if (elem.str != NULL)
- {
- ERROR1("Default for unknown element %s\n", uStringText(elem.str));
- ACTION1("Value for field %s ignored\n", uStringText(field.str));
- }
- else if (field.str != NULL)
- {
- ERROR1("Default defined for unknown field %s\n",
- uStringText(field.str));
- ACTION("Ignored\n");
- }
- return False;
-}
-
-static int
-HandleKeyTypeBody(VarDef * def,
- XkbDescPtr xkb, KeyTypeInfo * type, KeyTypesInfo * 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 = HandleKeyTypeVar(def, xkb, info);
- continue;
- }
- ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
- if (ok)
- ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value,
- info);
- }
- return ok;
-}
-
-/**
- * Process a type "XYZ" { } specification in the xkb_types section.
- *
- */
-static int
-HandleKeyTypeDef(KeyTypeDef * def,
- XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info)
-{
- register int i;
- KeyTypeInfo type;
-
- if (def->merge != MergeDefault)
- merge = def->merge;
-
- type.defs.defined = 0;
- type.defs.fileID = info->fileID;
- type.defs.merge = merge;
- type.defs.next = NULL;
- type.dpy = info->dpy;
- type.name = def->name;
- type.mask = info->dflt.mask;
- type.vmask = info->dflt.vmask;
- type.groupInfo = info->dflt.groupInfo;
- type.numLevels = 1;
- type.nEntries = type.szEntries = 0;
- type.entries = NULL;
- type.szNames = 0;
- type.lvlNames = NULL;
- type.preserve = NULL;
-
- /* Parse the actual content. */
- if (!HandleKeyTypeBody(def->body, xkb, &type, info))
- {
- info->errorCount++;
- return False;
- }
-
- /* now copy any appropriate map, preserve or level names from the */
- /* default type */
- for (i = 0; i < info->dflt.nEntries; i++)
- {
- XkbKTMapEntryPtr dflt;
- dflt = &info->dflt.entries[i];
- if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) &&
- ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods))
- {
- AddMapEntry(xkb, &type, dflt, False, False);
- }
- }
- if (info->dflt.preserve)
- {
- PreserveInfo *dflt = info->dflt.preserve;
- while (dflt)
- {
- if (((dflt->indexMods & type.mask) == dflt->indexMods) &&
- ((dflt->indexVMods & type.vmask) == dflt->indexVMods))
- {
- AddPreserve(xkb, &type, dflt, False, False);
- }
- dflt = (PreserveInfo *) dflt->defs.next;
- }
- }
- for (i = 0; i < info->dflt.szNames; i++)
- {
- if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None))
- {
- AddLevelName(&type, i, info->dflt.lvlNames[i], False, False);
- }
- }
- /* Now add the new keytype to the info struct */
- if (!AddKeyType(xkb, info, &type))
- {
- info->errorCount++;
- return False;
- }
- return True;
-}
-
-/**
- * Process an xkb_types section.
- *
- * @param file The parsed xkb_types section.
- * @param merge Merge Strategy (e.g. MergeOverride)
- * @param info Pointer to memory where the outcome will be stored.
- */
-static void
-HandleKeyTypesFile(XkbFile * file,
- XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info)
-{
- ParseCommon *stmt;
-
- info->name = uStringDup(file->name);
- stmt = file->defs;
- while (stmt)
- {
- switch (stmt->stmtType)
- {
- case StmtInclude:
- if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info,
- HandleKeyTypesFile))
- info->errorCount++;
- break;
- case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */
- if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info))
- info->errorCount++;
- break;
- case StmtVarDef:
- if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info))
- info->errorCount++;
- break;
- case StmtVModDef: /* virtual_modifiers NumLock, ... */
- if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
- info->errorCount++;
- break;
- case StmtKeyAliasDef:
- ERROR("Key type files may not include other declarations\n");
- ACTION("Ignoring definition of key alias\n");
- info->errorCount++;
- break;
- case StmtKeycodeDef:
- ERROR("Key type files may not include other declarations\n");
- ACTION("Ignoring definition of key name\n");
- info->errorCount++;
- break;
- case StmtInterpDef:
- ERROR("Key type files may not include other declarations\n");
- ACTION("Ignoring definition of symbol interpretation\n");
- info->errorCount++;
- break;
- default:
- WSGO1("Unexpected statement type %d in HandleKeyTypesFile\n",
- stmt->stmtType);
- break;
- }
- stmt = stmt->next;
- if (info->errorCount > 10)
- {
-#ifdef NOISY
- ERROR("Too many errors\n");
-#endif
- ACTION1("Abandoning keytypes file \"%s\"\n", file->topName);
- break;
- }
- }
- return;
-}
-
-static Bool
-CopyDefToKeyType(XkbDescPtr xkb, XkbKeyTypePtr type, KeyTypeInfo * def)
-{
- register int i;
- PreserveInfo *pre;
-
- for (pre = def->preserve; pre != NULL;
- pre = (PreserveInfo *) pre->defs.next)
- {
- XkbKTMapEntryPtr match;
- XkbKTMapEntryRec tmp;
- tmp.mods.real_mods = pre->indexMods;
- tmp.mods.vmods = pre->indexVMods;
- tmp.level = 0;
- AddMapEntry(xkb, def, &tmp, False, False);
- match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods);
- if (!match)
- {
- WSGO("Couldn't find matching entry for preserve\n");
- ACTION("Aborting\n");
- return False;
- }
- pre->matchingMapIndex = match - def->entries;
- }
- type->mods.real_mods = def->mask;
- type->mods.vmods = def->vmask;
- type->num_levels = def->numLevels;
- type->map_count = def->nEntries;
- type->map = def->entries;
- if (def->preserve)
- {
- type->preserve = uTypedCalloc(type->map_count, XkbModsRec);
- if (!type->preserve)
- {
- WARN("Couldn't allocate preserve array in CopyDefToKeyType\n");
- ACTION1("Preserve setting for type %s lost\n",
- XkbAtomText(def->dpy, def->name, XkbMessage));
- }
- else
- {
- pre = def->preserve;
- for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next)
- {
- int ndx = pre->matchingMapIndex;
- type->preserve[ndx].mask = pre->preMods;
- type->preserve[ndx].real_mods = pre->preMods;
- type->preserve[ndx].vmods = pre->preVMods;
- }
- }
- }
- else
- type->preserve = NULL;
- type->name = (Atom) def->name;
- if (def->szNames > 0)
- {
- type->level_names = uTypedCalloc(def->numLevels, Atom);
-
- /* assert def->szNames<=def->numLevels */
- for (i = 0; i < def->szNames; i++)
- {
- type->level_names[i] = (Atom) def->lvlNames[i];
- }
- }
- else
- {
- type->level_names = NULL;
- }
-
- def->nEntries = def->szEntries = 0;
- def->entries = NULL;
- return XkbComputeEffectiveMap(xkb, type, NULL);
-}
-
-Bool
-CompileKeyTypes(XkbFile * file, XkbFileInfo * result, unsigned merge)
-{
- KeyTypesInfo info;
- XkbDescPtr xkb;
-
- xkb = result->xkb;
- InitKeyTypesInfo(&info, xkb, NULL);
- info.fileID = file->id;
- HandleKeyTypesFile(file, xkb, merge, &info);
-
- if (info.errorCount == 0)
- {
- register int i;
- register KeyTypeInfo *def;
- register XkbKeyTypePtr type, next;
-
- if (info.name != NULL)
- {
- if (XkbAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success)
- xkb->names->types = XkbInternAtom(xkb->dpy, info.name, False);
- else
- {
- WSGO("Couldn't allocate space for types name\n");
- ACTION2("Name \"%s\" (from %s) NOT assigned\n",
- scanFile, info.name);
- }
- }
- i = info.nTypes;
- if ((info.stdPresent & XkbOneLevelMask) == 0)
- i++;
- if ((info.stdPresent & XkbTwoLevelMask) == 0)
- i++;
- if ((info.stdPresent & XkbKeypadMask) == 0)
- i++;
- if ((info.stdPresent & XkbAlphabeticMask) == 0)
- i++;
- if (XkbAllocClientMap(xkb, XkbKeyTypesMask, i) != Success)
- {
- WSGO("Couldn't allocate client map\n");
- ACTION("Exiting\n");
- return False;
- }
- xkb->map->num_types = i;
- if (XkbAllRequiredTypes & (~info.stdPresent))
- {
- unsigned missing, keypadVMod;
-
- missing = XkbAllRequiredTypes & (~info.stdPresent);
- keypadVMod = FindKeypadVMod(xkb);
- if (XkbInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success)
- {
- WSGO("Couldn't initialize canonical key types\n");
- ACTION("Exiting\n");
- return False;
- }
- if (missing & XkbOneLevelMask)
- xkb->map->types[XkbOneLevelIndex].name = tok_ONE_LEVEL;
- if (missing & XkbTwoLevelMask)
- xkb->map->types[XkbTwoLevelIndex].name = tok_TWO_LEVEL;
- if (missing & XkbAlphabeticMask)
- xkb->map->types[XkbAlphabeticIndex].name = tok_ALPHABETIC;
- if (missing & XkbKeypadMask)
- xkb->map->types[XkbKeypadIndex].name = tok_KEYPAD;
- }
- next = &xkb->map->types[XkbLastRequiredType + 1];
- for (i = 0, def = info.types; i < info.nTypes; i++)
- {
- if (def->name == tok_ONE_LEVEL)
- type = &xkb->map->types[XkbOneLevelIndex];
- else if (def->name == tok_TWO_LEVEL)
- type = &xkb->map->types[XkbTwoLevelIndex];
- else if (def->name == tok_ALPHABETIC)
- type = &xkb->map->types[XkbAlphabeticIndex];
- else if (def->name == tok_KEYPAD)
- type = &xkb->map->types[XkbKeypadIndex];
- else
- type = next++;
- DeleteLevel1MapEntries(def);
- if (!CopyDefToKeyType(xkb, type, def))
- return False;
- def = (KeyTypeInfo *) def->defs.next;
- }
- return True;
- }
- return False;
-}
+/************************************************************ + 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" + +typedef struct _PreserveInfo +{ + CommonInfo defs; + short matchingMapIndex; + unsigned char indexMods; + unsigned char preMods; + unsigned short indexVMods; + unsigned short preVMods; +} PreserveInfo; + +#define _KT_Name (1<<0) +#define _KT_Mask (1<<1) +#define _KT_Map (1<<2) +#define _KT_Preserve (1<<3) +#define _KT_LevelNames (1<<4) + +typedef struct _KeyTypeInfo +{ + CommonInfo defs; + Display *dpy; + Atom name; + int fileID; + unsigned mask; + unsigned vmask; + Bool groupInfo; + int numLevels; + int nEntries; + int szEntries; + XkbKTMapEntryPtr entries; + PreserveInfo *preserve; + int szNames; + Atom *lvlNames; +} KeyTypeInfo; + +typedef struct _KeyTypesInfo +{ + Display *dpy; + char *name; + int errorCount; + int fileID; + unsigned stdPresent; + int nTypes; + KeyTypeInfo *types; + KeyTypeInfo dflt; + VModInfo vmods; +} KeyTypesInfo; + +Atom tok_ONE_LEVEL; +Atom tok_TWO_LEVEL; +Atom tok_ALPHABETIC; +Atom tok_KEYPAD; + +/***====================================================================***/ + +#define ReportTypeShouldBeArray(t,f) \ + ReportShouldBeArray("key type",(f),TypeTxt(t)) +#define ReportTypeBadType(t,f,w) \ + ReportBadType("key type",(f),TypeTxt(t),(w)) + +/***====================================================================***/ + +extern Bool AddMapEntry(XkbDescPtr /* xkb */ , + KeyTypeInfo * /* type */ , + XkbKTMapEntryPtr /* new */ , + Bool /* clobber */ , + Bool /* report */ + ); + +extern Bool AddPreserve(XkbDescPtr /* xkb */ , + KeyTypeInfo * /* type */ , + PreserveInfo * /* new */ , + Bool /* clobber */ , + Bool /* report */ + ); + +extern Bool AddLevelName(KeyTypeInfo * /* type */ , + unsigned /* level */ , + Atom /* name */ , + Bool /* clobber */ , + Bool /* report */ + ); + +#define MapEntryTxt(t,x,e) \ + XkbVModMaskText((t)->dpy,(x),(e)->mods.real_mods,(e)->mods.vmods,XkbMessage) +#define PreserveIndexTxt(t,x,p) \ + XkbVModMaskText((t)->dpy,(x),(p)->indexMods,(p)->indexVMods,XkbMessage) +#define PreserveTxt(t,x,p) \ + XkbVModMaskText((t)->dpy,(x),(p)->preMods,(p)->preVMods,XkbMessage) +#define TypeTxt(t) XkbAtomText((t)->dpy,(t)->name,XkbMessage) +#define TypeMaskTxt(t,x) \ + XkbVModMaskText((t)->dpy,(x),(t)->mask,(t)->vmask,XkbMessage) + +/***====================================================================***/ + +static void +InitKeyTypesInfo(KeyTypesInfo * info, XkbDescPtr xkb, KeyTypesInfo * from) +{ + tok_ONE_LEVEL = XkbInternAtom(NULL, "ONE_LEVEL", False); + tok_TWO_LEVEL = XkbInternAtom(NULL, "TWO_LEVEL", False); + tok_ALPHABETIC = XkbInternAtom(NULL, "ALPHABETIC", False); + tok_KEYPAD = XkbInternAtom(NULL, "KEYPAD", False); + info->dpy = NULL; + info->name = uStringDup("default"); + info->errorCount = 0; + info->stdPresent = 0; + info->nTypes = 0; + info->types = NULL; + info->dflt.defs.defined = 0; + info->dflt.defs.fileID = 0; + info->dflt.defs.merge = MergeOverride; + info->dflt.defs.next = NULL; + info->dflt.name = None; + info->dflt.mask = 0; + info->dflt.vmask = 0; + info->dflt.groupInfo = False; + info->dflt.numLevels = 1; + info->dflt.nEntries = info->dflt.szEntries = 0; + info->dflt.entries = NULL; + info->dflt.szNames = 0; + info->dflt.lvlNames = NULL; + info->dflt.preserve = NULL; + InitVModInfo(&info->vmods, xkb); + if (from != NULL) + { + info->dpy = from->dpy; + info->dflt = from->dflt; + if (from->dflt.entries) + { + info->dflt.entries = uTypedCalloc(from->dflt.szEntries, + XkbKTMapEntryRec); + if (info->dflt.entries) + { + unsigned sz = from->dflt.nEntries * sizeof(XkbKTMapEntryRec); + memcpy(info->dflt.entries, from->dflt.entries, sz); + } + } + if (from->dflt.lvlNames) + { + info->dflt.lvlNames = uTypedCalloc(from->dflt.szNames, Atom); + if (info->dflt.lvlNames) + { + register unsigned sz = from->dflt.szNames * sizeof(Atom); + memcpy(info->dflt.lvlNames, from->dflt.lvlNames, sz); + } + } + if (from->dflt.preserve) + { + PreserveInfo *old, *new, *last; + last = NULL; + old = from->dflt.preserve; + for (; old; old = (PreserveInfo *) old->defs.next) + { + new = uTypedAlloc(PreserveInfo); + if (!new) + return; + *new = *old; + new->defs.next = NULL; + if (last) + last->defs.next = (CommonInfo *) new; + else + info->dflt.preserve = new; + last = new; + } + } + } + return; +} + +static void +FreeKeyTypeInfo(KeyTypeInfo * type) +{ + if (type->entries != NULL) + { + uFree(type->entries); + type->entries = NULL; + } + if (type->lvlNames != NULL) + { + uFree(type->lvlNames); + type->lvlNames = NULL; + } + if (type->preserve != NULL) + { + ClearCommonInfo(&type->preserve->defs); + type->preserve = NULL; + } + return; +} + +static void +FreeKeyTypesInfo(KeyTypesInfo * info) +{ + info->dpy = NULL; + if (info->name) + uFree(info->name); + info->name = NULL; + if (info->types) + { + register KeyTypeInfo *type; + for (type = info->types; type; type = (KeyTypeInfo *) type->defs.next) + { + FreeKeyTypeInfo(type); + } + info->types = (KeyTypeInfo *) ClearCommonInfo(&info->types->defs); + } + FreeKeyTypeInfo(&info->dflt); + return; +} + +static KeyTypeInfo * +NextKeyType(KeyTypesInfo * info) +{ + KeyTypeInfo *type; + + type = uTypedAlloc(KeyTypeInfo); + if (type != NULL) + { + bzero(type, sizeof(KeyTypeInfo)); + type->defs.fileID = info->fileID; + type->dpy = info->dpy; + info->types = (KeyTypeInfo *) AddCommonInfo(&info->types->defs, + (CommonInfo *) type); + info->nTypes++; + } + return type; +} + +static KeyTypeInfo * +FindMatchingKeyType(KeyTypesInfo * info, KeyTypeInfo * new) +{ + KeyTypeInfo *old; + + for (old = info->types; old; old = (KeyTypeInfo *) old->defs.next) + { + if (old->name == new->name) + return old; + } + return NULL; +} + +static Bool +ReportTypeBadWidth(const char *type, int has, int needs) +{ + ERROR3("Key type \"%s\" has %d levels, must have %d\n", type, has, needs); + ACTION("Illegal type definition ignored\n"); + return False; +} + +static Bool +AddKeyType(XkbDescPtr xkb, KeyTypesInfo * info, KeyTypeInfo * new) +{ + KeyTypeInfo *old; + + if (new->name == tok_ONE_LEVEL) + { + if (new->numLevels > 1) + return ReportTypeBadWidth("ONE_LEVEL", new->numLevels, 1); + info->stdPresent |= XkbOneLevelMask; + } + else if (new->name == tok_TWO_LEVEL) + { + if (new->numLevels > 2) + return ReportTypeBadWidth("TWO_LEVEL", new->numLevels, 2); + else if (new->numLevels < 2) + new->numLevels = 2; + info->stdPresent |= XkbTwoLevelMask; + } + else if (new->name == tok_ALPHABETIC) + { + if (new->numLevels > 2) + return ReportTypeBadWidth("ALPHABETIC", new->numLevels, 2); + else if (new->numLevels < 2) + new->numLevels = 2; + info->stdPresent |= XkbAlphabeticMask; + } + else if (new->name == tok_KEYPAD) + { + if (new->numLevels > 2) + return ReportTypeBadWidth("KEYPAD", new->numLevels, 2); + else if (new->numLevels < 2) + new->numLevels = 2; + info->stdPresent |= XkbKeypadMask; + } + + old = FindMatchingKeyType(info, new); + if (old != NULL) + { + Bool report; + if ((new->defs.merge == MergeReplace) + || (new->defs.merge == MergeOverride)) + { + KeyTypeInfo *next = (KeyTypeInfo *) old->defs.next; + if (((old->defs.fileID == new->defs.fileID) + && (warningLevel > 0)) || (warningLevel > 9)) + { + WARN1("Multiple definitions of the %s key type\n", + XkbAtomGetString(NULL, new->name)); + ACTION("Earlier definition ignored\n"); + } + FreeKeyTypeInfo(old); + *old = *new; + new->szEntries = new->nEntries = 0; + new->entries = NULL; + new->preserve = NULL; + new->lvlNames = NULL; + old->defs.next = &next->defs; + return True; + } + report = (old->defs.fileID == new->defs.fileID) && (warningLevel > 0); + if (report) + { + WARN1("Multiple definitions of the %s key type\n", + XkbAtomGetString(NULL, new->name)); + ACTION("Later definition ignored\n"); + } + FreeKeyTypeInfo(new); + return True; + } + old = NextKeyType(info); + if (old == NULL) + return False; + *old = *new; + old->defs.next = NULL; + new->nEntries = new->szEntries = 0; + new->entries = NULL; + new->szNames = 0; + new->lvlNames = NULL; + new->preserve = NULL; + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedKeyTypes(KeyTypesInfo * into, + KeyTypesInfo * from, unsigned merge, XkbDescPtr xkb) +{ + KeyTypeInfo *type; + + if (from->errorCount > 0) + { + into->errorCount += from->errorCount; + return; + } + if (into->name == NULL) + { + into->name = from->name; + from->name = NULL; + } + for (type = from->types; type; type = (KeyTypeInfo *) type->defs.next) + { + if (merge != MergeDefault) + type->defs.merge = merge; + if (!AddKeyType(xkb, into, type)) + into->errorCount++; + } + into->stdPresent |= from->stdPresent; + return; +} + +typedef void (*FileHandler) (XkbFile * /* file */ , + XkbDescPtr /* xkb */ , + unsigned /* merge */ , + KeyTypesInfo * /* included */ + ); + +static Bool +HandleIncludeKeyTypes(IncludeStmt * stmt, + XkbDescPtr xkb, KeyTypesInfo * info, FileHandler hndlr) +{ + unsigned newMerge; + XkbFile *rtrn; + KeyTypesInfo included; + Bool haveSelf; + + haveSelf = False; + if ((stmt->file == NULL) && (stmt->map == NULL)) + { + haveSelf = True; + included = *info; + bzero(info, sizeof(KeyTypesInfo)); + } + else if (ProcessIncludeFile(stmt, XkmTypesIndex, &rtrn, &newMerge)) + { + InitKeyTypesInfo(&included, xkb, info); + included.fileID = included.dflt.defs.fileID = rtrn->id; + included.dflt.defs.merge = newMerge; + + (*hndlr) (rtrn, xkb, newMerge, &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; + KeyTypesInfo next_incl; + + for (next = stmt->next; next != NULL; next = next->next) + { + if ((next->file == NULL) && (next->map == NULL)) + { + haveSelf = True; + MergeIncludedKeyTypes(&included, info, next->merge, xkb); + FreeKeyTypesInfo(info); + } + else if (ProcessIncludeFile(next, XkmTypesIndex, &rtrn, &op)) + { + InitKeyTypesInfo(&next_incl, xkb, &included); + next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id; + next_incl.dflt.defs.merge = op; + (*hndlr) (rtrn, xkb, op, &next_incl); + MergeIncludedKeyTypes(&included, &next_incl, op, xkb); + FreeKeyTypesInfo(&next_incl); + } + else + { + info->errorCount += 10; + return False; + } + } + } + if (haveSelf) + *info = included; + else + { + MergeIncludedKeyTypes(info, &included, newMerge, xkb); + FreeKeyTypesInfo(&included); + } + return (info->errorCount == 0); +} + +/***====================================================================***/ + +static XkbKTMapEntryPtr +FindMatchingMapEntry(KeyTypeInfo * type, unsigned mask, unsigned vmask) +{ + register int i; + XkbKTMapEntryPtr entry; + + for (i = 0, entry = type->entries; i < type->nEntries; i++, entry++) + { + if ((entry->mods.real_mods == mask) && (entry->mods.vmods == vmask)) + return entry; + } + return NULL; +} + +static void +DeleteLevel1MapEntries(KeyTypeInfo * type) +{ + register int i, n; + + for (i = 0; i < type->nEntries; i++) + { + if (type->entries[i].level == 0) + { + for (n = i; n < type->nEntries - 1; n++) + { + type->entries[n] = type->entries[n + 1]; + } + type->nEntries--; + } + } + return; +} + +/** + * Return a pointer to the next free XkbKTMapEntry, reallocating space if + * necessary. + */ +static XkbKTMapEntryPtr +NextMapEntry(KeyTypeInfo * type) +{ + if (type->entries == NULL) + { + type->entries = uTypedCalloc(2, XkbKTMapEntryRec); + if (type->entries == NULL) + { + ERROR1("Couldn't allocate map entries for %s\n", TypeTxt(type)); + ACTION("Map entries lost\n"); + return NULL; + } + type->szEntries = 2; + type->nEntries = 0; + } + else if (type->nEntries >= type->szEntries) + { + type->szEntries *= 2; + type->entries = uTypedRecalloc(type->entries, + type->nEntries, type->szEntries, + XkbKTMapEntryRec); + if (type->entries == NULL) + { + ERROR1("Couldn't reallocate map entries for %s\n", TypeTxt(type)); + ACTION("Map entries lost\n"); + return NULL; + } + } + return &type->entries[type->nEntries++]; +} + +Bool +AddPreserve(XkbDescPtr xkb, + KeyTypeInfo * type, PreserveInfo * new, Bool clobber, Bool report) +{ + PreserveInfo *old; + + old = type->preserve; + while (old != NULL) + { + if ((old->indexMods != new->indexMods) || + (old->indexVMods != new->indexVMods)) + { + old = (PreserveInfo *) old->defs.next; + continue; + } + if ((old->preMods == new->preMods) + && (old->preVMods == new->preVMods)) + { + if (warningLevel > 9) + { + WARN2("Identical definitions for preserve[%s] in %s\n", + PreserveIndexTxt(type, xkb, old), TypeTxt(type)); + ACTION("Ignored\n"); + } + return True; + } + if (report && (warningLevel > 0)) + { + char *str; + WARN2("Multiple definitions for preserve[%s] in %s\n", + PreserveIndexTxt(type, xkb, old), TypeTxt(type)); + + if (clobber) + str = PreserveTxt(type, xkb, new); + else + str = PreserveTxt(type, xkb, old); + ACTION1("Using %s, ", str); + if (clobber) + str = PreserveTxt(type, xkb, old); + else + str = PreserveTxt(type, xkb, new); + INFO1("ignoring %s\n", str); + } + if (clobber) + { + old->preMods = new->preMods; + old->preVMods = new->preVMods; + } + return True; + } + old = uTypedAlloc(PreserveInfo); + if (!old) + { + WSGO1("Couldn't allocate preserve in %s\n", TypeTxt(type)); + ACTION1("Preserve[%s] lost\n", PreserveIndexTxt(type, xkb, old)); + return False; + } + *old = *new; + old->matchingMapIndex = -1; + type->preserve = + (PreserveInfo *) AddCommonInfo(&type->preserve->defs, &old->defs); + return True; +} + +/** + * Add a new KTMapEntry to the given key type. If an entry with the same mods + * already exists, the level is updated (if clobber is TRUE). Otherwise, a new + * entry is created. + * + * @param clobber Overwrite existing entry. + * @param report True if a warning is to be printed on. + */ +Bool +AddMapEntry(XkbDescPtr xkb, + KeyTypeInfo * type, + XkbKTMapEntryPtr new, Bool clobber, Bool report) +{ + XkbKTMapEntryPtr old; + + if ((old = + FindMatchingMapEntry(type, new->mods.real_mods, new->mods.vmods))) + { + if (report && (old->level != new->level)) + { + unsigned use, ignore; + if (clobber) + { + use = new->level + 1; + ignore = old->level + 1; + } + else + { + use = old->level + 1; + ignore = new->level + 1; + } + WARN2("Multiple map entries for %s in %s\n", + MapEntryTxt(type, xkb, new), TypeTxt(type)); + ACTION2("Using %d, ignoring %d\n", use, ignore); + } + else if (warningLevel > 9) + { + WARN3("Multiple occurences of map[%s]= %d in %s\n", + MapEntryTxt(type, xkb, new), new->level + 1, TypeTxt(type)); + ACTION("Ignored\n"); + return True; + } + if (clobber) + old->level = new->level; + return True; + } + if ((old = NextMapEntry(type)) == NULL) + return False; /* allocation failure, already reported */ + if (new->level >= type->numLevels) + type->numLevels = new->level + 1; + if (new->mods.vmods == 0) + old->active = True; + else + old->active = False; + old->mods.mask = new->mods.real_mods; + old->mods.real_mods = new->mods.real_mods; + old->mods.vmods = new->mods.vmods; + old->level = new->level; + return True; +} + +static LookupEntry lnames[] = { + {"level1", 1}, + {"level2", 2}, + {"level3", 3}, + {"level4", 4}, + {"level5", 5}, + {"level6", 6}, + {"level7", 7}, + {"level8", 8}, + {NULL, 0} +}; + +static Bool +SetMapEntry(KeyTypeInfo * type, + XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value) +{ + ExprResult rtrn; + XkbKTMapEntryRec entry; + + if (arrayNdx == NULL) + return ReportTypeShouldBeArray(type, "map entry"); + if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb)) + return ReportTypeBadType(type, "map entry", "modifier mask"); + entry.mods.real_mods = rtrn.uval & 0xff; /* modifiers < 512 */ + entry.mods.vmods = (rtrn.uval >> 8) & 0xffff; /* modifiers > 512 */ + if ((entry.mods.real_mods & (~type->mask)) || + ((entry.mods.vmods & (~type->vmask)) != 0)) + { + if (warningLevel > 0) + { + WARN1("Map entry for unused modifiers in %s\n", TypeTxt(type)); + ACTION1("Using %s instead of ", + XkbVModMaskText(type->dpy, xkb, + entry.mods.real_mods & type->mask, + entry.mods.vmods & type->vmask, + XkbMessage)); + INFO1("%s\n", MapEntryTxt(type, xkb, &entry)); + } + entry.mods.real_mods &= type->mask; + entry.mods.vmods &= type->vmask; + } + if (!ExprResolveInteger(value, &rtrn, SimpleLookup, (XPointer) lnames)) + { + ERROR("Level specifications in a key type must be integer\n"); + ACTION("Ignoring malformed level specification\n"); + return False; + } + if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1)) + { + ERROR3("Shift level %d out of range (1..%d) in key type %s\n", + XkbMaxShiftLevel + 1, rtrn.ival, TypeTxt(type)); + ACTION1("Ignoring illegal definition of map[%s]\n", + MapEntryTxt(type, xkb, &entry)); + return False; + } + entry.level = rtrn.ival - 1; + return AddMapEntry(xkb, type, &entry, True, True); +} + +static Bool +SetPreserve(KeyTypeInfo * type, + XkbDescPtr xkb, ExprDef * arrayNdx, ExprDef * value) +{ + ExprResult rtrn; + PreserveInfo new; + + if (arrayNdx == NULL) + return ReportTypeShouldBeArray(type, "preserve entry"); + if (!ExprResolveModMask(arrayNdx, &rtrn, LookupVModMask, (XPointer) xkb)) + return ReportTypeBadType(type, "preserve entry", "modifier mask"); + new.defs = type->defs; + new.defs.next = NULL; + new.indexMods = rtrn.uval & 0xff; + new.indexVMods = (rtrn.uval >> 8) & 0xffff; + if ((new.indexMods & (~type->mask)) || (new.indexVMods & (~type->vmask))) + { + if (warningLevel > 0) + { + WARN1("Preserve for modifiers not used by the %s type\n", + TypeTxt(type)); + ACTION1("Index %s converted to ", + PreserveIndexTxt(type, xkb, &new)); + } + new.indexMods &= type->mask; + new.indexVMods &= type->vmask; + if (warningLevel > 0) + INFO1("%s\n", PreserveIndexTxt(type, xkb, &new)); + } + if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb)) + { + ERROR("Preserve value in a key type is not a modifier mask\n"); + ACTION2("Ignoring preserve[%s] in type %s\n", + PreserveIndexTxt(type, xkb, &new), TypeTxt(type)); + return False; + } + new.preMods = rtrn.uval & 0xff; + new.preVMods = (rtrn.uval >> 16) & 0xffff; + if ((new.preMods & (~new.indexMods)) + || (new.preVMods && (~new.indexVMods))) + { + if (warningLevel > 0) + { + WARN2("Illegal value for preserve[%s] in type %s\n", + PreserveTxt(type, xkb, &new), TypeTxt(type)); + ACTION1("Converted %s to ", PreserveIndexTxt(type, xkb, &new)); + } + new.preMods &= new.indexMods; + new.preVMods &= new.indexVMods; + if (warningLevel > 0) + { + INFO1("%s\n", PreserveIndexTxt(type, xkb, &new)); + } + } + return AddPreserve(xkb, type, &new, True, True); +} + +/***====================================================================***/ + +Bool +AddLevelName(KeyTypeInfo * type, + unsigned level, Atom name, Bool clobber, Bool report) +{ + if ((type->lvlNames == NULL) || (type->szNames <= level)) + { + type->lvlNames = + uTypedRecalloc(type->lvlNames, type->szNames, level + 1, Atom); + if (type->lvlNames == NULL) + { + ERROR1("Couldn't allocate level names for type %s\n", + TypeTxt(type)); + ACTION("Level names lost\n"); + type->szNames = 0; + return False; + } + type->szNames = level + 1; + } + else if (type->lvlNames[level] == name) + { + if (warningLevel > 9) + { + WARN2("Duplicate names for level %d of key type %s\n", + level + 1, TypeTxt(type)); + ACTION("Ignored\n"); + } + return True; + } + else if (type->lvlNames[level] != None) + { + if (warningLevel > 0) + { + char *old, *new; + old = XkbAtomText(type->dpy, type->lvlNames[level], XkbMessage); + new = XkbAtomText(type->dpy, name, XkbMessage); + WARN2("Multiple names for level %d of key type %s\n", + level + 1, TypeTxt(type)); + if (clobber) + ACTION2("Using %s, ignoring %s\n", new, old); + else + ACTION2("Using %s, ignoring %s\n", old, new); + } + if (!clobber) + return True; + } + if (level >= type->numLevels) + type->numLevels = level + 1; + type->lvlNames[level] = name; + return True; +} + +static Bool +SetLevelName(KeyTypeInfo * type, ExprDef * arrayNdx, ExprDef * value) +{ + ExprResult rtrn; + unsigned level; + + if (arrayNdx == NULL) + return ReportTypeShouldBeArray(type, "level name"); + if (!ExprResolveInteger(arrayNdx, &rtrn, SimpleLookup, (XPointer) lnames)) + return ReportTypeBadType(type, "level name", "integer"); + if ((rtrn.ival < 1) || (rtrn.ival > XkbMaxShiftLevel + 1)) + { + ERROR3("Level name %d out of range (1..%d) in key type %s\n", + rtrn.ival, + XkbMaxShiftLevel + 1, + XkbAtomText(type->dpy, type->name, XkbMessage)); + ACTION("Ignoring illegal level name definition\n"); + return False; + } + level = rtrn.ival - 1; + if (!ExprResolveString(value, &rtrn, NULL, NULL)) + { + ERROR2("Non-string name for level %d in key type %s\n", level + 1, + XkbAtomText(type->dpy, type->name, XkbMessage)); + ACTION("Ignoring illegal level name definition\n"); + return False; + } + return + AddLevelName(type, level, XkbInternAtom(NULL, rtrn.str, False), True, + True); +} + +/***====================================================================***/ + +/** + * Parses the fields in a type "..." { } description. + * + * @param field The field to parse (e.g. modifiers, map, level_name) + */ +static Bool +SetKeyTypeField(KeyTypeInfo * type, + XkbDescPtr xkb, + char *field, + ExprDef * arrayNdx, ExprDef * value, KeyTypesInfo * info) +{ + ExprResult tmp; + + if (uStrCaseCmp(field, "modifiers") == 0) + { + unsigned mods, vmods; + if (arrayNdx != NULL) + { + WARN("The modifiers field of a key type is not an array\n"); + ACTION("Illegal array subscript ignored\n"); + } + /* get modifier mask for current type */ + if (!ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb)) + { + ERROR("Key type mask field must be a modifier mask\n"); + ACTION("Key type definition ignored\n"); + return False; + } + mods = tmp.uval & 0xff; /* core mods */ + vmods = (tmp.uval >> 8) & 0xffff; /* xkb virtual mods */ + if (type->defs.defined & _KT_Mask) + { + WARN1("Multiple modifier mask definitions for key type %s\n", + XkbAtomText(type->dpy, type->name, XkbMessage)); + ACTION1("Using %s, ", TypeMaskTxt(type, xkb)); + INFO1("ignoring %s\n", XkbVModMaskText(type->dpy, xkb, mods, + vmods, XkbMessage)); + return False; + } + type->mask = mods; + type->vmask = vmods; + type->defs.defined |= _KT_Mask; + return True; + } + else if (uStrCaseCmp(field, "map") == 0) + { + type->defs.defined |= _KT_Map; + return SetMapEntry(type, xkb, arrayNdx, value); + } + else if (uStrCaseCmp(field, "preserve") == 0) + { + type->defs.defined |= _KT_Preserve; + return SetPreserve(type, xkb, arrayNdx, value); + } + else if ((uStrCaseCmp(field, "levelname") == 0) || + (uStrCaseCmp(field, "level_name") == 0)) + { + type->defs.defined |= _KT_LevelNames; + return SetLevelName(type, arrayNdx, value); + } + ERROR2("Unknown field %s in key type %s\n", field, TypeTxt(type)); + ACTION("Definition ignored\n"); + return False; +} + +static Bool +HandleKeyTypeVar(VarDef * stmt, XkbDescPtr xkb, KeyTypesInfo * info) +{ + ExprResult elem, field; + ExprDef *arrayNdx; + + if (!ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx)) + return False; /* internal error, already reported */ + if (elem.str && (uStrCaseCmp(elem.str, "type") == 0)) + return SetKeyTypeField(&info->dflt, xkb, field.str, arrayNdx, + stmt->value, info); + if (elem.str != NULL) + { + ERROR1("Default for unknown element %s\n", uStringText(elem.str)); + ACTION1("Value for field %s ignored\n", uStringText(field.str)); + } + else if (field.str != NULL) + { + ERROR1("Default defined for unknown field %s\n", + uStringText(field.str)); + ACTION("Ignored\n"); + } + return False; +} + +static int +HandleKeyTypeBody(VarDef * def, + XkbDescPtr xkb, KeyTypeInfo * type, KeyTypesInfo * 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 = HandleKeyTypeVar(def, xkb, info); + continue; + } + ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx); + if (ok) + ok = SetKeyTypeField(type, xkb, field.str, arrayNdx, def->value, + info); + } + return ok; +} + +/** + * Process a type "XYZ" { } specification in the xkb_types section. + * + */ +static int +HandleKeyTypeDef(KeyTypeDef * def, + XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info) +{ + register int i; + KeyTypeInfo type; + + if (def->merge != MergeDefault) + merge = def->merge; + + type.defs.defined = 0; + type.defs.fileID = info->fileID; + type.defs.merge = merge; + type.defs.next = NULL; + type.dpy = info->dpy; + type.name = def->name; + type.mask = info->dflt.mask; + type.vmask = info->dflt.vmask; + type.groupInfo = info->dflt.groupInfo; + type.numLevels = 1; + type.nEntries = type.szEntries = 0; + type.entries = NULL; + type.szNames = 0; + type.lvlNames = NULL; + type.preserve = NULL; + + /* Parse the actual content. */ + if (!HandleKeyTypeBody(def->body, xkb, &type, info)) + { + info->errorCount++; + return False; + } + + /* now copy any appropriate map, preserve or level names from the */ + /* default type */ + for (i = 0; i < info->dflt.nEntries; i++) + { + XkbKTMapEntryPtr dflt; + dflt = &info->dflt.entries[i]; + if (((dflt->mods.real_mods & type.mask) == dflt->mods.real_mods) && + ((dflt->mods.vmods & type.vmask) == dflt->mods.vmods)) + { + AddMapEntry(xkb, &type, dflt, False, False); + } + } + if (info->dflt.preserve) + { + PreserveInfo *dflt = info->dflt.preserve; + while (dflt) + { + if (((dflt->indexMods & type.mask) == dflt->indexMods) && + ((dflt->indexVMods & type.vmask) == dflt->indexVMods)) + { + AddPreserve(xkb, &type, dflt, False, False); + } + dflt = (PreserveInfo *) dflt->defs.next; + } + } + for (i = 0; i < info->dflt.szNames; i++) + { + if ((i < type.numLevels) && (info->dflt.lvlNames[i] != None)) + { + AddLevelName(&type, i, info->dflt.lvlNames[i], False, False); + } + } + /* Now add the new keytype to the info struct */ + if (!AddKeyType(xkb, info, &type)) + { + info->errorCount++; + return False; + } + return True; +} + +/** + * Process an xkb_types section. + * + * @param file The parsed xkb_types section. + * @param merge Merge Strategy (e.g. MergeOverride) + * @param info Pointer to memory where the outcome will be stored. + */ +static void +HandleKeyTypesFile(XkbFile * file, + XkbDescPtr xkb, unsigned merge, KeyTypesInfo * info) +{ + ParseCommon *stmt; + + info->name = uStringDup(file->name); + stmt = file->defs; + while (stmt) + { + switch (stmt->stmtType) + { + case StmtInclude: + if (!HandleIncludeKeyTypes((IncludeStmt *) stmt, xkb, info, + HandleKeyTypesFile)) + info->errorCount++; + break; + case StmtKeyTypeDef: /* e.g. type "ONE_LEVEL" */ + if (!HandleKeyTypeDef((KeyTypeDef *) stmt, xkb, merge, info)) + info->errorCount++; + break; + case StmtVarDef: + if (!HandleKeyTypeVar((VarDef *) stmt, xkb, info)) + info->errorCount++; + break; + case StmtVModDef: /* virtual_modifiers NumLock, ... */ + if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods)) + info->errorCount++; + break; + case StmtKeyAliasDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of key alias\n"); + info->errorCount++; + break; + case StmtKeycodeDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of key name\n"); + info->errorCount++; + break; + case StmtInterpDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of symbol interpretation\n"); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleKeyTypesFile\n", + stmt->stmtType); + break; + } + stmt = stmt->next; + if (info->errorCount > 10) + { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning keytypes file \"%s\"\n", file->topName); + break; + } + } + return; +} + +static Bool +CopyDefToKeyType(XkbDescPtr xkb, XkbKeyTypePtr type, KeyTypeInfo * def) +{ + register int i; + PreserveInfo *pre; + + for (pre = def->preserve; pre != NULL; + pre = (PreserveInfo *) pre->defs.next) + { + XkbKTMapEntryPtr match; + XkbKTMapEntryRec tmp; + tmp.mods.real_mods = pre->indexMods; + tmp.mods.vmods = pre->indexVMods; + tmp.level = 0; + AddMapEntry(xkb, def, &tmp, False, False); + match = FindMatchingMapEntry(def, pre->indexMods, pre->indexVMods); + if (!match) + { + WSGO("Couldn't find matching entry for preserve\n"); + ACTION("Aborting\n"); + return False; + } + pre->matchingMapIndex = match - def->entries; + } + type->mods.real_mods = def->mask; + type->mods.vmods = def->vmask; + type->num_levels = def->numLevels; + type->map_count = def->nEntries; + type->map = def->entries; + if (def->preserve) + { + type->preserve = uTypedCalloc(type->map_count, XkbModsRec); + if (!type->preserve) + { + WARN("Couldn't allocate preserve array in CopyDefToKeyType\n"); + ACTION1("Preserve setting for type %s lost\n", + XkbAtomText(def->dpy, def->name, XkbMessage)); + } + else + { + pre = def->preserve; + for (; pre != NULL; pre = (PreserveInfo *) pre->defs.next) + { + int ndx = pre->matchingMapIndex; + type->preserve[ndx].mask = pre->preMods; + type->preserve[ndx].real_mods = pre->preMods; + type->preserve[ndx].vmods = pre->preVMods; + } + } + } + else + type->preserve = NULL; + type->name = (Atom) def->name; + if (def->szNames > 0) + { + type->level_names = uTypedCalloc(def->numLevels, Atom); + + /* assert def->szNames<=def->numLevels */ + for (i = 0; i < def->szNames; i++) + { + type->level_names[i] = (Atom) def->lvlNames[i]; + } + } + else + { + type->level_names = NULL; + } + + def->nEntries = def->szEntries = 0; + def->entries = NULL; + return XkbComputeEffectiveMap(xkb, type, NULL); +} + +Bool +CompileKeyTypes(XkbFile * file, XkbFileInfo * result, unsigned merge) +{ + KeyTypesInfo info; + XkbDescPtr xkb; + + xkb = result->xkb; + InitKeyTypesInfo(&info, xkb, NULL); + info.fileID = file->id; + HandleKeyTypesFile(file, xkb, merge, &info); + + if (info.errorCount == 0) + { + register int i; + register KeyTypeInfo *def; + register XkbKeyTypePtr type, next; + + if (info.name != NULL) + { + if (XkbAllocNames(xkb, XkbTypesNameMask, 0, 0) == Success) + xkb->names->types = XkbInternAtom(xkb->dpy, info.name, False); + else + { + WSGO("Couldn't allocate space for types name\n"); + ACTION2("Name \"%s\" (from %s) NOT assigned\n", + scanFile, info.name); + } + } + i = info.nTypes; + if ((info.stdPresent & XkbOneLevelMask) == 0) + i++; + if ((info.stdPresent & XkbTwoLevelMask) == 0) + i++; + if ((info.stdPresent & XkbKeypadMask) == 0) + i++; + if ((info.stdPresent & XkbAlphabeticMask) == 0) + i++; + if (XkbAllocClientMap(xkb, XkbKeyTypesMask, i) != Success) + { + WSGO("Couldn't allocate client map\n"); + ACTION("Exiting\n"); + return False; + } + xkb->map->num_types = i; + if (XkbAllRequiredTypes & (~info.stdPresent)) + { + unsigned missing, keypadVMod; + + missing = XkbAllRequiredTypes & (~info.stdPresent); + keypadVMod = FindKeypadVMod(xkb); + if (XkbInitCanonicalKeyTypes(xkb, missing, keypadVMod) != Success) + { + WSGO("Couldn't initialize canonical key types\n"); + ACTION("Exiting\n"); + return False; + } + if (missing & XkbOneLevelMask) + xkb->map->types[XkbOneLevelIndex].name = tok_ONE_LEVEL; + if (missing & XkbTwoLevelMask) + xkb->map->types[XkbTwoLevelIndex].name = tok_TWO_LEVEL; + if (missing & XkbAlphabeticMask) + xkb->map->types[XkbAlphabeticIndex].name = tok_ALPHABETIC; + if (missing & XkbKeypadMask) + xkb->map->types[XkbKeypadIndex].name = tok_KEYPAD; + } + next = &xkb->map->types[XkbLastRequiredType + 1]; + for (i = 0, def = info.types; i < info.nTypes; i++) + { + if (def->name == tok_ONE_LEVEL) + type = &xkb->map->types[XkbOneLevelIndex]; + else if (def->name == tok_TWO_LEVEL) + type = &xkb->map->types[XkbTwoLevelIndex]; + else if (def->name == tok_ALPHABETIC) + type = &xkb->map->types[XkbAlphabeticIndex]; + else if (def->name == tok_KEYPAD) + type = &xkb->map->types[XkbKeypadIndex]; + else + type = next++; + DeleteLevel1MapEntries(def); + if (!CopyDefToKeyType(xkb, type, def)) + return False; + def = (KeyTypeInfo *) def->defs.next; + } + return True; + } + return False; +} diff --git a/xkbcomp/misc.c b/xkbcomp/misc.c index 51bd14a84..4990a7439 100644 --- a/xkbcomp/misc.c +++ b/xkbcomp/misc.c @@ -1,581 +1,581 @@ -/************************************************************
- 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;
- char tmpname[XkbKeyNameLength + 1];
-
- 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);
- }
- snprintf(tmpname, sizeof(tmpname), "U%03d",
- nUnknown++);
- memcpy(xkb->names->keys[i].name, tmpname,
- XkbKeyNameLength);
- }
- 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);
- snprintf(tmpname, sizeof(tmpname), "U%03d", nUnknown++);
- memcpy(xkb->names->keys[i].name, tmpname,
- XkbKeyNameLength);
- }
- }
- }
- }
- 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;
-}
+/************************************************************ + 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; + char tmpname[XkbKeyNameLength + 1]; + + 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); + } + snprintf(tmpname, sizeof(tmpname), "U%03d", + nUnknown++); + memcpy(xkb->names->keys[i].name, tmpname, + XkbKeyNameLength); + } + 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); + snprintf(tmpname, sizeof(tmpname), "U%03d", nUnknown++); + memcpy(xkb->names->keys[i].name, tmpname, + XkbKeyNameLength); + } + } + } + } + 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; +} diff --git a/xkbcomp/misc.h b/xkbcomp/misc.h index f6c489255..4fa4b6dde 100644 --- a/xkbcomp/misc.h +++ b/xkbcomp/misc.h @@ -1,111 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/tokens.h b/xkbcomp/tokens.h index 54d4d149b..970f3d4de 100644 --- a/xkbcomp/tokens.h +++ b/xkbcomp/tokens.h @@ -1,104 +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
+/************************************************************ + 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 diff --git a/xkbcomp/utils.c b/xkbcomp/utils.c index cabe9e2b0..55efbe11f 100644 --- a/xkbcomp/utils.c +++ b/xkbcomp/utils.c @@ -1,434 +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
+ + /*\ + * + * 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 diff --git a/xkbcomp/vmod.c b/xkbcomp/vmod.c index 8d08a9ba1..5578fd01f 100644 --- a/xkbcomp/vmod.c +++ b/xkbcomp/vmod.c @@ -1,271 +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;
-}
+/************************************************************ + 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; +} diff --git a/xkbcomp/vmod.h b/xkbcomp/vmod.h index 61bfc6a24..559b9d504 100644 --- a/xkbcomp/vmod.h +++ b/xkbcomp/vmod.h @@ -1,78 +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 */
+/************************************************************ + 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 */ diff --git a/xkbcomp/xkbpath.c b/xkbcomp/xkbpath.c index 3408aa45b..68020129e 100644 --- a/xkbcomp/xkbpath.c +++ b/xkbcomp/xkbpath.c @@ -1,420 +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;
-}
+/************************************************************ + 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; +} diff --git a/xkbcomp/xkbpath.h b/xkbcomp/xkbpath.h index e9ebeda0e..66c3ab76b 100644 --- a/xkbcomp/xkbpath.h +++ b/xkbcomp/xkbpath.h @@ -1,65 +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_ */
+/************************************************************ + 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_ */ |