alias.c revision 34345a63
1f46a6179Smrg/************************************************************ 2f46a6179Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 3f46a6179Smrg 4f46a6179Smrg Permission to use, copy, modify, and distribute this 5f46a6179Smrg software and its documentation for any purpose and without 6f46a6179Smrg fee is hereby granted, provided that the above copyright 7f46a6179Smrg notice appear in all copies and that both that copyright 8f46a6179Smrg notice and this permission notice appear in supporting 9f46a6179Smrg documentation, and that the name of Silicon Graphics not be 10f46a6179Smrg used in advertising or publicity pertaining to distribution 11f46a6179Smrg of the software without specific prior written permission. 12f46a6179Smrg Silicon Graphics makes no representation about the suitability 13f46a6179Smrg of this software for any purpose. It is provided "as is" 14f46a6179Smrg without any express or implied warranty. 15f46a6179Smrg 16f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24f46a6179Smrg 25f46a6179Smrg ********************************************************/ 26f46a6179Smrg 27f46a6179Smrg#include "xkbcomp.h" 28f46a6179Smrg#include "misc.h" 29f46a6179Smrg#include "alias.h" 30f46a6179Smrg#include "keycodes.h" 31f46a6179Smrg 32f46a6179Smrg#include <X11/extensions/XKBgeom.h> 33f46a6179Smrg 34f46a6179Smrgstatic void 3534345a63SmrgHandleCollision(AliasInfo * old, AliasInfo * new) 36f46a6179Smrg{ 3734345a63Smrg if (strncmp(new->real, old->real, XkbKeyNameLength) == 0) 3834345a63Smrg { 3934345a63Smrg if (((new->def.fileID == old->def.fileID) && (warningLevel > 0)) || 4034345a63Smrg (warningLevel > 9)) 4134345a63Smrg { 4234345a63Smrg WARN2("Alias of %s for %s declared more than once\n", 4334345a63Smrg XkbKeyNameText(new->alias, XkbMessage), 4434345a63Smrg XkbKeyNameText(new->real, XkbMessage)); 4534345a63Smrg ACTION("First definition ignored\n"); 4634345a63Smrg } 47f46a6179Smrg } 4834345a63Smrg else 4934345a63Smrg { 5034345a63Smrg char *use, *ignore; 5134345a63Smrg if (new->def.merge == MergeAugment) 5234345a63Smrg { 5334345a63Smrg use = old->real; 5434345a63Smrg ignore = new->real; 5534345a63Smrg } 5634345a63Smrg else 5734345a63Smrg { 5834345a63Smrg use = new->real; 5934345a63Smrg ignore = old->real; 6034345a63Smrg } 6134345a63Smrg if (((old->def.fileID == new->def.fileID) && (warningLevel > 0)) || 6234345a63Smrg (warningLevel > 9)) 6334345a63Smrg { 6434345a63Smrg WARN1("Multiple definitions for alias %s\n", 6534345a63Smrg XkbKeyNameText(old->alias, XkbMessage)); 6634345a63Smrg ACTION2("Using %s, ignoring %s\n", 6734345a63Smrg XkbKeyNameText(use, XkbMessage), 6834345a63Smrg XkbKeyNameText(ignore, XkbMessage)); 6934345a63Smrg } 7034345a63Smrg if (use != old->real) 7134345a63Smrg memcpy(old->real, use, XkbKeyNameLength); 72f46a6179Smrg } 7334345a63Smrg old->def.fileID = new->def.fileID; 7434345a63Smrg old->def.merge = new->def.merge; 75f46a6179Smrg return; 76f46a6179Smrg} 77f46a6179Smrg 78f46a6179Smrgstatic void 7934345a63SmrgInitAliasInfo(AliasInfo * info, 8034345a63Smrg unsigned merge, unsigned file_id, char *alias, char *real) 81f46a6179Smrg{ 8234345a63Smrg bzero(info, sizeof(AliasInfo)); 8334345a63Smrg info->def.merge = merge; 8434345a63Smrg info->def.fileID = file_id; 8534345a63Smrg strncpy(info->alias, alias, XkbKeyNameLength); 8634345a63Smrg strncpy(info->real, real, XkbKeyNameLength); 87f46a6179Smrg return; 88f46a6179Smrg} 89f46a6179Smrg 9034345a63Smrgint 9134345a63SmrgHandleAliasDef(KeyAliasDef * def, 9234345a63Smrg unsigned merge, unsigned file_id, AliasInfo ** info_in) 93f46a6179Smrg{ 9434345a63Smrg AliasInfo *info; 95f46a6179Smrg 9634345a63Smrg for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next) 9734345a63Smrg { 9834345a63Smrg if (strncmp(info->alias, def->alias, XkbKeyNameLength) == 0) 9934345a63Smrg { 10034345a63Smrg AliasInfo new; 10134345a63Smrg InitAliasInfo(&new, merge, file_id, def->alias, def->real); 10234345a63Smrg HandleCollision(info, &new); 10334345a63Smrg return True; 10434345a63Smrg } 105f46a6179Smrg } 10634345a63Smrg info = uTypedCalloc(1, AliasInfo); 10734345a63Smrg if (info == NULL) 10834345a63Smrg { 10934345a63Smrg WSGO("Allocation failure in HandleAliasDef\n"); 11034345a63Smrg return False; 111f46a6179Smrg } 11234345a63Smrg info->def.fileID = file_id; 11334345a63Smrg info->def.merge = merge; 11434345a63Smrg info->def.next = (CommonInfo *) * info_in; 11534345a63Smrg memcpy(info->alias, def->alias, XkbKeyNameLength); 11634345a63Smrg memcpy(info->real, def->real, XkbKeyNameLength); 11734345a63Smrg *info_in = (AliasInfo *) AddCommonInfo(&(*info_in)->def, &info->def); 118f46a6179Smrg return True; 119f46a6179Smrg} 120f46a6179Smrg 121f46a6179Smrgvoid 12234345a63SmrgClearAliases(AliasInfo ** info_in) 123f46a6179Smrg{ 12434345a63Smrg if ((info_in) && (*info_in)) 12534345a63Smrg ClearCommonInfo(&(*info_in)->def); 126f46a6179Smrg return; 127f46a6179Smrg} 128f46a6179Smrg 129f46a6179SmrgBool 13034345a63SmrgMergeAliases(AliasInfo ** into, AliasInfo ** merge, unsigned how_merge) 131f46a6179Smrg{ 13234345a63Smrg AliasInfo *tmp; 13334345a63Smrg KeyAliasDef def; 134f46a6179Smrg 13534345a63Smrg if ((*merge) == NULL) 13634345a63Smrg return True; 13734345a63Smrg if ((*into) == NULL) 13834345a63Smrg { 13934345a63Smrg *into = *merge; 14034345a63Smrg *merge = NULL; 14134345a63Smrg return True; 14234345a63Smrg } 14334345a63Smrg bzero((char *) &def, sizeof(KeyAliasDef)); 14434345a63Smrg for (tmp = *merge; tmp != NULL; tmp = (AliasInfo *) tmp->def.next) 14534345a63Smrg { 14634345a63Smrg if (how_merge == MergeDefault) 14734345a63Smrg def.merge = tmp->def.merge; 14834345a63Smrg else 14934345a63Smrg def.merge = how_merge; 15034345a63Smrg memcpy(def.alias, tmp->alias, XkbKeyNameLength); 15134345a63Smrg memcpy(def.real, tmp->real, XkbKeyNameLength); 15234345a63Smrg if (!HandleAliasDef(&def, def.merge, tmp->def.fileID, into)) 15334345a63Smrg return False; 154f46a6179Smrg } 155f46a6179Smrg return True; 156f46a6179Smrg} 157f46a6179Smrg 158f46a6179Smrgint 15934345a63SmrgApplyAliases(XkbDescPtr xkb, Bool toGeom, AliasInfo ** info_in) 160f46a6179Smrg{ 16134345a63Smrg register int i; 16234345a63Smrg XkbKeyAliasPtr old, a; 16334345a63Smrg AliasInfo *info; 16434345a63Smrg int nNew, nOld; 16534345a63Smrg Status status; 166f46a6179Smrg 16734345a63Smrg if (*info_in == NULL) 16834345a63Smrg return True; 16934345a63Smrg if (toGeom) 17034345a63Smrg { 17134345a63Smrg nOld = (xkb->geom ? xkb->geom->num_key_aliases : 0); 17234345a63Smrg old = (xkb->geom ? xkb->geom->key_aliases : NULL); 173f46a6179Smrg } 17434345a63Smrg else 17534345a63Smrg { 17634345a63Smrg nOld = (xkb->names ? xkb->names->num_key_aliases : 0); 17734345a63Smrg old = (xkb->names ? xkb->names->key_aliases : NULL); 178f46a6179Smrg } 17934345a63Smrg for (nNew = 0, info = *info_in; info != NULL; 18034345a63Smrg info = (AliasInfo *) info->def.next) 18134345a63Smrg { 18234345a63Smrg unsigned long lname; 18334345a63Smrg unsigned int kc; 184f46a6179Smrg 18534345a63Smrg lname = KeyNameToLong(info->real); 18634345a63Smrg if (!FindNamedKey(xkb, lname, &kc, False, CreateKeyNames(xkb), 0)) 18734345a63Smrg { 18834345a63Smrg if (warningLevel > 4) 18934345a63Smrg { 19034345a63Smrg WARN2("Attempt to alias %s to non-existent key %s\n", 19134345a63Smrg XkbKeyNameText(info->alias, XkbMessage), 19234345a63Smrg XkbKeyNameText(info->real, XkbMessage)); 19334345a63Smrg ACTION("Ignored\n"); 19434345a63Smrg } 19534345a63Smrg info->alias[0] = '\0'; 19634345a63Smrg continue; 19734345a63Smrg } 19834345a63Smrg lname = KeyNameToLong(info->alias); 19934345a63Smrg if (FindNamedKey(xkb, lname, &kc, False, False, 0)) 20034345a63Smrg { 20134345a63Smrg if (warningLevel > 4) 20234345a63Smrg { 20334345a63Smrg WARN("Attempt to create alias with the name of a real key\n"); 20434345a63Smrg ACTION2("Alias \"%s = %s\" ignored\n", 20534345a63Smrg XkbKeyNameText(info->alias, XkbMessage), 20634345a63Smrg XkbKeyNameText(info->real, XkbMessage)); 20734345a63Smrg } 20834345a63Smrg info->alias[0] = '\0'; 20934345a63Smrg continue; 21034345a63Smrg } 21134345a63Smrg nNew++; 21234345a63Smrg if (old) 21334345a63Smrg { 21434345a63Smrg for (i = 0, a = old; i < nOld; i++, a++) 21534345a63Smrg { 21634345a63Smrg if (strncmp(a->alias, info->alias, XkbKeyNameLength) == 0) 21734345a63Smrg { 21834345a63Smrg AliasInfo old; 21934345a63Smrg InitAliasInfo(&old, MergeAugment, 0, a->alias, a->real); 22034345a63Smrg HandleCollision(&old, info); 22134345a63Smrg memcpy(old.real, a->real, XkbKeyNameLength); 22234345a63Smrg info->alias[0] = '\0'; 22334345a63Smrg nNew--; 22434345a63Smrg break; 22534345a63Smrg } 22634345a63Smrg } 22734345a63Smrg } 228f46a6179Smrg } 22934345a63Smrg if (nNew == 0) 23034345a63Smrg { 23134345a63Smrg ClearCommonInfo(&(*info_in)->def); 23234345a63Smrg *info_in = NULL; 23334345a63Smrg return True; 234f46a6179Smrg } 23534345a63Smrg status = Success; 23634345a63Smrg if (toGeom) 23734345a63Smrg { 23834345a63Smrg if (!xkb->geom) 23934345a63Smrg { 24034345a63Smrg XkbGeometrySizesRec sizes; 24134345a63Smrg bzero((char *) &sizes, sizeof(XkbGeometrySizesRec)); 24234345a63Smrg sizes.which = XkbGeomKeyAliasesMask; 24334345a63Smrg sizes.num_key_aliases = nOld + nNew; 24434345a63Smrg status = XkbAllocGeometry(xkb, &sizes); 24534345a63Smrg } 24634345a63Smrg else 24734345a63Smrg { 24834345a63Smrg status = XkbAllocGeomKeyAliases(xkb->geom, nOld + nNew); 24934345a63Smrg } 25034345a63Smrg if (xkb->geom) 25134345a63Smrg old = xkb->geom->key_aliases; 252f46a6179Smrg } 25334345a63Smrg else 25434345a63Smrg { 25534345a63Smrg status = XkbAllocNames(xkb, XkbKeyAliasesMask, 0, nOld + nNew); 25634345a63Smrg if (xkb->names) 25734345a63Smrg old = xkb->names->key_aliases; 258f46a6179Smrg } 25934345a63Smrg if (status != Success) 26034345a63Smrg { 26134345a63Smrg WSGO("Allocation failure in ApplyAliases\n"); 26234345a63Smrg return False; 263f46a6179Smrg } 26434345a63Smrg if (toGeom) 26534345a63Smrg a = &xkb->geom->key_aliases[nOld]; 26634345a63Smrg else 26734345a63Smrg a = &xkb->names->key_aliases[nOld]; 26834345a63Smrg for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next) 26934345a63Smrg { 27034345a63Smrg if (info->alias[0] != '\0') 27134345a63Smrg { 27234345a63Smrg strncpy(a->alias, info->alias, XkbKeyNameLength); 27334345a63Smrg strncpy(a->real, info->real, XkbKeyNameLength); 27434345a63Smrg a++; 27534345a63Smrg } 276f46a6179Smrg } 277f46a6179Smrg#ifdef DEBUG 27834345a63Smrg if ((a - old) != (nOld + nNew)) 27934345a63Smrg { 28034345a63Smrg WSGO2("Expected %d aliases total but created %d\n", nOld + nNew, 28134345a63Smrg a - old); 282f46a6179Smrg } 283f46a6179Smrg#endif 28434345a63Smrg if (toGeom) 28534345a63Smrg xkb->geom->num_key_aliases += nNew; 286f46a6179Smrg ClearCommonInfo(&(*info_in)->def); 28734345a63Smrg *info_in = NULL; 288f46a6179Smrg return True; 289f46a6179Smrg} 290