1 /************************************************************ 2 * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3 * 4 * Permission to use, copy, modify, and distribute this 5 * software and its documentation for any purpose and without 6 * fee is hereby granted, provided that the above copyright 7 * notice appear in all copies and that both that copyright 8 * notice and this permission notice appear in supporting 9 * documentation, and that the name of Silicon Graphics not be 10 * used in advertising or publicity pertaining to distribution 11 * of the software without specific prior written permission. 12 * Silicon Graphics makes no representation about the suitability 13 * of this software for any purpose. It is provided "as is" 14 * without any express or implied warranty. 15 * 16 * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 * THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 ********************************************************/ 26 27 #include "xkbcomp-priv.h" 28 #include "text.h" 29 #include "expr.h" 30 #include "vmod.h" 31 32 bool 33 HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods, 34 VModDef *stmt, enum merge_mode merge) 35 { 36 xkb_mod_index_t i; 37 struct xkb_mod *mod; 38 xkb_mod_mask_t mapping; 39 40 merge = (merge == MERGE_DEFAULT ? stmt->merge : merge); 41 42 if (stmt->value) { 43 /* 44 * This is a statement such as 'virtualModifiers NumLock = Mod1'; 45 * it sets the vmod-to-real-mod[s] mapping directly instead of going 46 * through modifier_map or some such. 47 */ 48 if (!ExprResolveModMask(ctx, stmt->value, MOD_REAL, mods, &mapping)) { 49 log_err(ctx, 50 "Declaration of %s ignored\n", 51 xkb_atom_text(ctx, stmt->name)); 52 return false; 53 } 54 } 55 else { 56 mapping = 0; 57 } 58 59 xkb_mods_enumerate(i, mod, mods) { 60 if (mod->name == stmt->name) { 61 if (mod->type != MOD_VIRT) { 62 log_err(ctx, 63 "Can't add a virtual modifier named \"%s\"; " 64 "there is already a non-virtual modifier with this name! Ignored\n", 65 xkb_atom_text(ctx, mod->name)); 66 return false; 67 } 68 69 if (mod->mapping == mapping) 70 return true; 71 72 if (mod->mapping != 0) { 73 xkb_mod_mask_t use, ignore; 74 75 use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping); 76 ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping); 77 78 log_warn(ctx, 79 "Virtual modifier %s defined multiple times; " 80 "Using %s, ignoring %s\n", 81 xkb_atom_text(ctx, stmt->name), 82 ModMaskText(ctx, mods, use), 83 ModMaskText(ctx, mods, ignore)); 84 85 mapping = use; 86 } 87 88 mod->mapping = mapping; 89 return true; 90 } 91 } 92 93 if (mods->num_mods >= XKB_MAX_MODS) { 94 log_err(ctx, 95 "Too many modifiers defined (maximum %d)\n", 96 XKB_MAX_MODS); 97 return false; 98 } 99 100 mods->mods[mods->num_mods].name = stmt->name; 101 mods->mods[mods->num_mods].type = MOD_VIRT; 102 mods->mods[mods->num_mods].mapping = mapping; 103 mods->num_mods++; 104 return true; 105 } 106