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