/************************************************************ * 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-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; }