alias.c revision f46a6179
1f46a6179Smrg/* $Xorg: alias.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ 2f46a6179Smrg/************************************************************ 3f46a6179Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 4f46a6179Smrg 5f46a6179Smrg Permission to use, copy, modify, and distribute this 6f46a6179Smrg software and its documentation for any purpose and without 7f46a6179Smrg fee is hereby granted, provided that the above copyright 8f46a6179Smrg notice appear in all copies and that both that copyright 9f46a6179Smrg notice and this permission notice appear in supporting 10f46a6179Smrg documentation, and that the name of Silicon Graphics not be 11f46a6179Smrg used in advertising or publicity pertaining to distribution 12f46a6179Smrg of the software without specific prior written permission. 13f46a6179Smrg Silicon Graphics makes no representation about the suitability 14f46a6179Smrg of this software for any purpose. It is provided "as is" 15f46a6179Smrg without any express or implied warranty. 16f46a6179Smrg 17f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 25f46a6179Smrg 26f46a6179Smrg ********************************************************/ 27f46a6179Smrg/* $XFree86$ */ 28f46a6179Smrg 29f46a6179Smrg#include "xkbcomp.h" 30f46a6179Smrg#include "misc.h" 31f46a6179Smrg#include "alias.h" 32f46a6179Smrg#include "keycodes.h" 33f46a6179Smrg 34f46a6179Smrg#include <X11/extensions/XKBgeom.h> 35f46a6179Smrg 36f46a6179Smrgstatic void 37f46a6179SmrgHandleCollision(AliasInfo *old,AliasInfo *new) 38f46a6179Smrg{ 39f46a6179Smrg if (strncmp(new->real,old->real,XkbKeyNameLength)==0) { 40f46a6179Smrg if (((new->def.fileID==old->def.fileID)&&(warningLevel>0))|| 41f46a6179Smrg (warningLevel>9)) { 42f46a6179Smrg WARN2("Alias of %s for %s declared more than once\n", 43f46a6179Smrg XkbKeyNameText(new->alias,XkbMessage), 44f46a6179Smrg XkbKeyNameText(new->real,XkbMessage)); 45f46a6179Smrg ACTION("First definition ignored\n"); 46f46a6179Smrg } 47f46a6179Smrg } 48f46a6179Smrg else { 49f46a6179Smrg char *use,*ignore; 50f46a6179Smrg if (new->def.merge==MergeAugment) { 51f46a6179Smrg use= old->real; 52f46a6179Smrg ignore= new->real; 53f46a6179Smrg } 54f46a6179Smrg else { 55f46a6179Smrg use= new->real; 56f46a6179Smrg ignore= old->real; 57f46a6179Smrg } 58f46a6179Smrg if (((old->def.fileID==new->def.fileID)&&(warningLevel>0))|| 59f46a6179Smrg (warningLevel>9)){ 60f46a6179Smrg WARN1("Multiple definitions for alias %s\n", 61f46a6179Smrg XkbKeyNameText(old->alias,XkbMessage)); 62f46a6179Smrg ACTION2("Using %s, ignoring %s\n", XkbKeyNameText(use,XkbMessage), 63f46a6179Smrg XkbKeyNameText(ignore,XkbMessage)); 64f46a6179Smrg } 65f46a6179Smrg if (use!=old->real) 66f46a6179Smrg memcpy(old->real,use,XkbKeyNameLength); 67f46a6179Smrg } 68f46a6179Smrg old->def.fileID= new->def.fileID; 69f46a6179Smrg old->def.merge= new->def.merge; 70f46a6179Smrg return; 71f46a6179Smrg} 72f46a6179Smrg 73f46a6179Smrgstatic void 74f46a6179SmrgInitAliasInfo( AliasInfo * info, 75f46a6179Smrg unsigned merge, 76f46a6179Smrg unsigned file_id, 77f46a6179Smrg char * alias, 78f46a6179Smrg char * real) 79f46a6179Smrg{ 80f46a6179Smrg bzero(info,sizeof(AliasInfo)); 81f46a6179Smrg info->def.merge= merge; 82f46a6179Smrg info->def.fileID= file_id; 83f46a6179Smrg strncpy(info->alias,alias,XkbKeyNameLength); 84f46a6179Smrg strncpy(info->real,real,XkbKeyNameLength); 85f46a6179Smrg return; 86f46a6179Smrg} 87f46a6179Smrg 88f46a6179Smrgint 89f46a6179SmrgHandleAliasDef( KeyAliasDef * def, 90f46a6179Smrg unsigned merge, 91f46a6179Smrg unsigned file_id, 92f46a6179Smrg AliasInfo ** info_in) 93f46a6179Smrg{ 94f46a6179SmrgAliasInfo * info; 95f46a6179Smrg 96f46a6179Smrg for (info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { 97f46a6179Smrg if (strncmp(info->alias,def->alias,XkbKeyNameLength)==0) { 98f46a6179Smrg AliasInfo new; 99f46a6179Smrg InitAliasInfo(&new,merge,file_id,def->alias,def->real); 100f46a6179Smrg HandleCollision(info,&new); 101f46a6179Smrg return True; 102f46a6179Smrg } 103f46a6179Smrg } 104f46a6179Smrg info= uTypedCalloc(1,AliasInfo); 105f46a6179Smrg if (info==NULL) { 106f46a6179Smrg WSGO("Allocation failure in HandleAliasDef\n"); 107f46a6179Smrg return False; 108f46a6179Smrg } 109f46a6179Smrg info->def.fileID= file_id; 110f46a6179Smrg info->def.merge= merge; 111f46a6179Smrg info->def.next= (CommonInfo *)*info_in; 112f46a6179Smrg memcpy(info->alias,def->alias,XkbKeyNameLength); 113f46a6179Smrg memcpy(info->real,def->real,XkbKeyNameLength); 114f46a6179Smrg *info_in= (AliasInfo *)AddCommonInfo(&(*info_in)->def,&info->def); 115f46a6179Smrg return True; 116f46a6179Smrg} 117f46a6179Smrg 118f46a6179Smrgvoid 119f46a6179SmrgClearAliases(AliasInfo **info_in) 120f46a6179Smrg{ 121f46a6179Smrg if ((info_in)&&(*info_in)) 122f46a6179Smrg ClearCommonInfo(&(*info_in)->def); 123f46a6179Smrg return; 124f46a6179Smrg} 125f46a6179Smrg 126f46a6179SmrgBool 127f46a6179SmrgMergeAliases(AliasInfo **into,AliasInfo **merge,unsigned how_merge) 128f46a6179Smrg{ 129f46a6179SmrgAliasInfo * tmp; 130f46a6179SmrgKeyAliasDef def; 131f46a6179Smrg 132f46a6179Smrg if ((*merge)==NULL) 133f46a6179Smrg return True; 134f46a6179Smrg if ((*into)==NULL) { 135f46a6179Smrg *into= *merge; 136f46a6179Smrg *merge= NULL; 137f46a6179Smrg return True; 138f46a6179Smrg } 139f46a6179Smrg bzero((char *)&def,sizeof(KeyAliasDef)); 140f46a6179Smrg for (tmp= *merge;tmp!=NULL;tmp= (AliasInfo *)tmp->def.next) { 141f46a6179Smrg if (how_merge==MergeDefault) 142f46a6179Smrg def.merge= tmp->def.merge; 143f46a6179Smrg else def.merge= how_merge; 144f46a6179Smrg memcpy(def.alias,tmp->alias,XkbKeyNameLength); 145f46a6179Smrg memcpy(def.real,tmp->real,XkbKeyNameLength); 146f46a6179Smrg if (!HandleAliasDef(&def,def.merge,tmp->def.fileID,into)) 147f46a6179Smrg return False; 148f46a6179Smrg } 149f46a6179Smrg return True; 150f46a6179Smrg} 151f46a6179Smrg 152f46a6179Smrgint 153f46a6179SmrgApplyAliases(XkbDescPtr xkb,Bool toGeom,AliasInfo **info_in) 154f46a6179Smrg{ 155f46a6179Smrgregister int i; 156f46a6179SmrgXkbKeyAliasPtr old,a; 157f46a6179SmrgAliasInfo * info; 158f46a6179Smrgint nNew,nOld; 159f46a6179SmrgStatus status; 160f46a6179Smrg 161f46a6179Smrg if (*info_in==NULL) 162f46a6179Smrg return True; 163f46a6179Smrg if (toGeom) { 164f46a6179Smrg nOld= (xkb->geom?xkb->geom->num_key_aliases:0); 165f46a6179Smrg old= (xkb->geom?xkb->geom->key_aliases:NULL); 166f46a6179Smrg } 167f46a6179Smrg else { 168f46a6179Smrg nOld= (xkb->names?xkb->names->num_key_aliases:0); 169f46a6179Smrg old= (xkb->names?xkb->names->key_aliases:NULL); 170f46a6179Smrg } 171f46a6179Smrg for (nNew=0,info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { 172f46a6179Smrg unsigned long lname; 173f46a6179Smrg unsigned int kc; 174f46a6179Smrg 175f46a6179Smrg lname= KeyNameToLong(info->real); 176f46a6179Smrg if (!FindNamedKey(xkb,lname,&kc,False,CreateKeyNames(xkb),0)) { 177f46a6179Smrg if (warningLevel>4) { 178f46a6179Smrg WARN2("Attempt to alias %s to non-existent key %s\n", 179f46a6179Smrg XkbKeyNameText(info->alias,XkbMessage), 180f46a6179Smrg XkbKeyNameText(info->real,XkbMessage)); 181f46a6179Smrg ACTION("Ignored\n"); 182f46a6179Smrg } 183f46a6179Smrg info->alias[0]= '\0'; 184f46a6179Smrg continue; 185f46a6179Smrg } 186f46a6179Smrg lname= KeyNameToLong(info->alias); 187f46a6179Smrg if (FindNamedKey(xkb,lname,&kc,False,False,0)) { 188f46a6179Smrg if (warningLevel>4) { 189f46a6179Smrg WARN("Attempt to create alias with the name of a real key\n"); 190f46a6179Smrg ACTION2("Alias \"%s = %s\" ignored\n", 191f46a6179Smrg XkbKeyNameText(info->alias,XkbMessage), 192f46a6179Smrg XkbKeyNameText(info->real,XkbMessage)); 193f46a6179Smrg } 194f46a6179Smrg info->alias[0]= '\0'; 195f46a6179Smrg continue; 196f46a6179Smrg } 197f46a6179Smrg nNew++; 198f46a6179Smrg if ( old ) { 199f46a6179Smrg for (i=0,a=old;i<nOld;i++,a++) { 200f46a6179Smrg if (strncmp(a->alias,info->alias,XkbKeyNameLength)==0) { 201f46a6179Smrg AliasInfo old; 202f46a6179Smrg InitAliasInfo(&old,MergeAugment,0,a->alias,a->real); 203f46a6179Smrg HandleCollision(&old,info); 204f46a6179Smrg memcpy(old.real,a->real,XkbKeyNameLength); 205f46a6179Smrg info->alias[0]= '\0'; 206f46a6179Smrg nNew--; 207f46a6179Smrg break; 208f46a6179Smrg } 209f46a6179Smrg } 210f46a6179Smrg } 211f46a6179Smrg } 212f46a6179Smrg if (nNew==0) { 213f46a6179Smrg ClearCommonInfo(&(*info_in)->def); 214f46a6179Smrg *info_in= NULL; 215f46a6179Smrg return True; 216f46a6179Smrg } 217f46a6179Smrg status= Success; 218f46a6179Smrg if (toGeom) { 219f46a6179Smrg if (!xkb->geom) { 220f46a6179Smrg XkbGeometrySizesRec sizes; 221f46a6179Smrg bzero((char *)&sizes,sizeof(XkbGeometrySizesRec)); 222f46a6179Smrg sizes.which= XkbGeomKeyAliasesMask; 223f46a6179Smrg sizes.num_key_aliases= nOld+nNew; 224f46a6179Smrg status= XkbAllocGeometry(xkb,&sizes); 225f46a6179Smrg } 226f46a6179Smrg else { 227f46a6179Smrg status= XkbAllocGeomKeyAliases(xkb->geom,nOld+nNew); 228f46a6179Smrg } 229f46a6179Smrg if (xkb->geom) 230f46a6179Smrg old= xkb->geom->key_aliases; 231f46a6179Smrg } 232f46a6179Smrg else { 233f46a6179Smrg status= XkbAllocNames(xkb,XkbKeyAliasesMask,0,nOld+nNew); 234f46a6179Smrg if (xkb->names) 235f46a6179Smrg old= xkb->names->key_aliases; 236f46a6179Smrg } 237f46a6179Smrg if (status!=Success) { 238f46a6179Smrg WSGO("Allocation failure in ApplyAliases\n"); 239f46a6179Smrg return False; 240f46a6179Smrg } 241f46a6179Smrg if (toGeom) 242f46a6179Smrg a= &xkb->geom->key_aliases[nOld]; 243f46a6179Smrg else a= &xkb->names->key_aliases[nOld]; 244f46a6179Smrg for (info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { 245f46a6179Smrg if (info->alias[0]!='\0') { 246f46a6179Smrg strncpy(a->alias,info->alias,XkbKeyNameLength); 247f46a6179Smrg strncpy(a->real,info->real,XkbKeyNameLength); 248f46a6179Smrg a++; 249f46a6179Smrg } 250f46a6179Smrg } 251f46a6179Smrg#ifdef DEBUG 252f46a6179Smrg if ((a-old)!=(nOld+nNew)) { 253f46a6179Smrg WSGO2("Expected %d aliases total but created %d\n",nOld+nNew,a-old); 254f46a6179Smrg } 255f46a6179Smrg#endif 256f46a6179Smrg if (toGeom) 257f46a6179Smrg xkb->geom->num_key_aliases+= nNew; 258f46a6179Smrg ClearCommonInfo(&(*info_in)->def); 259f46a6179Smrg *info_in= NULL; 260f46a6179Smrg return True; 261f46a6179Smrg} 262