1 /************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
32 #include <X11/extensions/XKBgeomcommon.h>
35 HandleCollision(AliasInfo * old, AliasInfo * new)
37 if (strncmp(new->real, old->real, XkbKeyNameLength) == 0)
39 if (((new->def.fileID == old->def.fileID) && (warningLevel > 0)) ||
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");
51 if (new->def.merge == MergeAugment)
61 if (((old->def.fileID == new->def.fileID) && (warningLevel > 0)) ||
64 WARN1("Multiple definitions for alias %s\n",
65 XkbKeyNameText(old->alias, XkbMessage));
66 ACTION2("Using %s, ignoring %s\n",
67 XkbKeyNameText(use, XkbMessage),
68 XkbKeyNameText(ignore, XkbMessage));
71 memcpy(old->real, use, XkbKeyNameLength);
73 old->def.fileID = new->def.fileID;
74 old->def.merge = new->def.merge;
79 InitAliasInfo(AliasInfo * info,
80 unsigned merge, unsigned file_id, char *alias, char *real)
82 bzero(info, sizeof(AliasInfo));
83 info->def.merge = merge;
84 info->def.fileID = file_id;
85 strncpy(info->alias, alias, XkbKeyNameLength);
86 strncpy(info->real, real, XkbKeyNameLength);
91 HandleAliasDef(KeyAliasDef * def,
92 unsigned merge, unsigned file_id, AliasInfo ** info_in)
96 for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next)
98 if (strncmp(info->alias, def->alias, XkbKeyNameLength) == 0)
101 InitAliasInfo(&new, merge, file_id, def->alias, def->real);
102 HandleCollision(info, &new);
106 info = uTypedCalloc(1, AliasInfo);
109 WSGO("Allocation failure in HandleAliasDef\n");
112 info->def.fileID = file_id;
113 info->def.merge = merge;
114 info->def.next = (CommonInfo *) * info_in;
115 memcpy(info->alias, def->alias, XkbKeyNameLength);
116 memcpy(info->real, def->real, XkbKeyNameLength);
117 *info_in = (AliasInfo *) AddCommonInfo(&(*info_in)->def, &info->def);
122 ClearAliases(AliasInfo ** info_in)
124 if ((info_in) && (*info_in))
125 ClearCommonInfo(&(*info_in)->def);
130 MergeAliases(AliasInfo ** into, AliasInfo ** merge, unsigned how_merge)
135 if ((*merge) == NULL)
143 bzero((char *) &def, sizeof(KeyAliasDef));
144 for (tmp = *merge; tmp != NULL; tmp = (AliasInfo *) tmp->def.next)
146 if (how_merge == MergeDefault)
147 def.merge = tmp->def.merge;
149 def.merge = how_merge;
150 memcpy(def.alias, tmp->alias, XkbKeyNameLength);
151 memcpy(def.real, tmp->real, XkbKeyNameLength);
152 if (!HandleAliasDef(&def, def.merge, tmp->def.fileID, into))
159 ApplyAliases(XkbcDescPtr xkb, Bool toGeom, AliasInfo ** info_in)
162 XkbKeyAliasPtr old, a;
167 if (*info_in == NULL)
171 nOld = (xkb->geom ? xkb->geom->num_key_aliases : 0);
172 old = (xkb->geom ? xkb->geom->key_aliases : NULL);
176 nOld = (xkb->names ? xkb->names->num_key_aliases : 0);
177 old = (xkb->names ? xkb->names->key_aliases : NULL);
179 for (nNew = 0, info = *info_in; info != NULL;
180 info = (AliasInfo *) info->def.next)
185 lname = KeyNameToLong(info->real);
186 if (!FindNamedKey(xkb, lname, &kc, False, CreateKeyNames(xkb), 0))
188 if (warningLevel > 4)
190 WARN2("Attempt to alias %s to non-existent key %s\n",
191 XkbKeyNameText(info->alias, XkbMessage),
192 XkbKeyNameText(info->real, XkbMessage));
195 info->alias[0] = '\0';
198 lname = KeyNameToLong(info->alias);
199 if (FindNamedKey(xkb, lname, &kc, False, False, 0))
201 if (warningLevel > 4)
203 WARN("Attempt to create alias with the name of a real key\n");
204 ACTION2("Alias \"%s = %s\" ignored\n",
205 XkbKeyNameText(info->alias, XkbMessage),
206 XkbKeyNameText(info->real, XkbMessage));
208 info->alias[0] = '\0';
214 for (i = 0, a = old; i < nOld; i++, a++)
216 if (strncmp(a->alias, info->alias, XkbKeyNameLength) == 0)
219 InitAliasInfo(&old, MergeAugment, 0, a->alias, a->real);
220 HandleCollision(&old, info);
221 memcpy(old.real, a->real, XkbKeyNameLength);
222 info->alias[0] = '\0';
231 ClearCommonInfo(&(*info_in)->def);
240 XkbGeometrySizesRec sizes;
241 bzero((char *) &sizes, sizeof(XkbGeometrySizesRec));
242 sizes.which = XkbGeomKeyAliasesMask;
243 sizes.num_key_aliases = nOld + nNew;
244 status = XkbAllocGeometry(xkb, &sizes);
248 status = XkbAllocGeomKeyAliases(xkb->geom, nOld + nNew);
251 old = xkb->geom->key_aliases;
255 status = XkbAllocNames(xkb, XkbKeyAliasesMask, 0, nOld + nNew);
257 old = xkb->names->key_aliases;
259 if (status != Success)
261 WSGO("Allocation failure in ApplyAliases\n");
265 a = &xkb->geom->key_aliases[nOld];
267 a = &xkb->names->key_aliases[nOld];
268 for (info = *info_in; info != NULL; info = (AliasInfo *) info->def.next)
270 if (info->alias[0] != '\0')
272 strncpy(a->alias, info->alias, XkbKeyNameLength);
273 strncpy(a->real, info->real, XkbKeyNameLength);
278 if ((a - old) != (nOld + nNew))
280 WSGO2("Expected %d aliases total but created %d\n", nOld + nNew,
285 xkb->geom->num_key_aliases += nNew;
286 ClearCommonInfo(&(*info_in)->def);