From 3744281b9ae8aa0ab86ceaee1afe8a603e3aeb2c Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 19 Nov 2012 10:16:38 +0100 Subject: dos -> unix --- xkbcomp/.gitignore | 160 +-- xkbcomp/COPYING | 180 ++-- xkbcomp/action.c | 2936 +++++++++++++++++++++++++------------------------- xkbcomp/action.h | 172 +-- xkbcomp/alias.h | 112 +- xkbcomp/autogen.sh | 26 +- xkbcomp/compat.h | 14 +- xkbcomp/expr.c | 2130 ++++++++++++++++++------------------ xkbcomp/expr.h | 344 +++--- xkbcomp/indicators.c | 1150 ++++++++++---------- xkbcomp/indicators.h | 176 +-- xkbcomp/keycodes.c | 1788 +++++++++++++++--------------- xkbcomp/keycodes.h | 80 +- xkbcomp/keymap.c | 366 +++---- xkbcomp/keytypes.c | 2586 ++++++++++++++++++++++---------------------- xkbcomp/misc.c | 1162 ++++++++++---------- xkbcomp/misc.h | 222 ++-- xkbcomp/tokens.h | 208 ++-- xkbcomp/utils.c | 868 +++++++-------- xkbcomp/vmod.c | 542 +++++----- xkbcomp/vmod.h | 156 +-- xkbcomp/xkbpath.c | 840 +++++++-------- xkbcomp/xkbpath.h | 130 +-- 23 files changed, 8174 insertions(+), 8174 deletions(-) (limited to 'xkbcomp') 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 - -/***====================================================================***/ - -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 + +/***====================================================================***/ + +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. = 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. = 9; */ - if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info)) - info->errorCount++; - break; - case StmtKeyAliasDef: /* e.g. alias = ; */ - 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. = 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. = 9; */ + if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info)) + info->errorCount++; + break; + case StmtKeyAliasDef: /* e.g. alias = ; */ + 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 -#include "parseutils.h" - -#include - -/***====================================================================***/ - -/** - * 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 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 \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 +#include "parseutils.h" + +#include + +/***====================================================================***/ + +/** + * 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 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 \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 -#include -#include - -/***====================================================================***/ - -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 +#include +#include + +/***====================================================================***/ + +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 -#include "xkbcomp.h" -#include "tokens.h" -#include "expr.h" -#include "misc.h" - -#include -#include - -#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 +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "misc.h" + +#include +#include + +#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 -#include - -#define DEBUG_VAR debugFlags -#include "utils.h" -#include -#include -#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 +#include + +#define DEBUG_VAR debugFlags +#include "utils.h" +#include +#include +#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_ */ -- cgit v1.2.3