diff options
Diffstat (limited to 'src/xkbcomp/vmod.c')
-rw-r--r-- | src/xkbcomp/vmod.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/xkbcomp/vmod.c b/src/xkbcomp/vmod.c new file mode 100644 index 0000000..0e8ac12 --- /dev/null +++ b/src/xkbcomp/vmod.c @@ -0,0 +1,107 @@ +/************************************************************ + * 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 "config.h" + +#include "xkbcomp-priv.h" +#include "text.h" +#include "expr.h" +#include "vmod.h" + +bool +HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods, + VModDef *stmt, enum merge_mode merge) +{ + xkb_mod_index_t i; + struct xkb_mod *mod; + xkb_mod_mask_t mapping; + + merge = (merge == MERGE_DEFAULT ? stmt->merge : merge); + + if (stmt->value) { + /* + * This is a statement such as 'virtualModifiers NumLock = Mod1'; + * it sets the vmod-to-real-mod[s] mapping directly instead of going + * through modifier_map or some such. + */ + if (!ExprResolveModMask(ctx, stmt->value, MOD_REAL, mods, &mapping)) { + log_err(ctx, + "Declaration of %s ignored\n", + xkb_atom_text(ctx, stmt->name)); + return false; + } + } + else { + mapping = 0; + } + + xkb_mods_enumerate(i, mod, mods) { + if (mod->name == stmt->name) { + if (mod->type != MOD_VIRT) { + log_err(ctx, + "Can't add a virtual modifier named \"%s\"; " + "there is already a non-virtual modifier with this name! Ignored\n", + xkb_atom_text(ctx, mod->name)); + return false; + } + + if (mod->mapping == mapping) + return true; + + if (mod->mapping != 0) { + xkb_mod_mask_t use, ignore; + + use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping); + ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping); + + log_warn(ctx, + "Virtual modifier %s defined multiple times; " + "Using %s, ignoring %s\n", + xkb_atom_text(ctx, stmt->name), + ModMaskText(ctx, mods, use), + ModMaskText(ctx, mods, ignore)); + + mapping = use; + } + + mod->mapping = mapping; + return true; + } + } + + if (mods->num_mods >= XKB_MAX_MODS) { + log_err(ctx, + "Too many modifiers defined (maximum %d)\n", + XKB_MAX_MODS); + return false; + } + + mods->mods[mods->num_mods].name = stmt->name; + mods->mods[mods->num_mods].type = MOD_VIRT; + mods->mods[mods->num_mods].mapping = mapping; + mods->num_mods++; + return true; +} |