1 /************************************************************
2 Copyright (c) 1994 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 ********************************************************/
33 #include <X11/keysym.h>
34 #include "parseutils.h"
36 /***====================================================================***/
39 * Open the file given in the include statement and parse it's content.
40 * If the statement defines a specific map to use, this map is returned in
41 * file_rtrn. Otherwise, the default map is returned.
43 * @param stmt The include statement, specifying the file name to look for.
44 * @param file_type Type of file (XkmKeyNamesIdx, etc.)
45 * @param file_rtrn Returns the key map to be used.
46 * @param merge_rtrn Always returns stmt->merge.
48 * @return True on success or False otherwise.
51 ProcessIncludeFile(IncludeStmt * stmt,
53 XkbFile ** file_rtrn, unsigned *merge_rtrn)
56 XkbFile *rtrn, *mapToUse, *next;
57 char oldFile[1024] = {0};
58 int oldLine = lineNum;
60 file = XkbFindFileInPath(stmt->file, file_type, &stmt->path);
63 ERROR("Can't find file \"%s\" for %s include\n", stmt->file,
64 XkbDirectoryForInclude(file_type));
68 strcpy(oldFile, scanFile);
70 memset(oldFile, 0, sizeof(oldFile));
72 setScanState(stmt->file, 1);
74 if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
76 setScanState(oldFile, oldLine);
77 ERROR("Error interpreting include file \"%s\"\n", stmt->file);
84 if (stmt->map != NULL)
88 next = (XkbFile *)mapToUse->common.next;
89 mapToUse->common.next = NULL;
90 if (strcmp(mapToUse->name, stmt->map) == 0 &&
91 mapToUse->type == file_type)
98 FreeXKBFile(mapToUse);
104 ERROR("No %s named \"%s\" in the include file \"%s\"\n",
105 XkbcConfigText(file_type), stmt->map, stmt->file);
109 else if ((rtrn->common.next != NULL) && (warningLevel > 5))
111 WARN("No map in include statement, but \"%s\" contains several\n",
113 ACTION("Using first defined map, \"%s\"\n", rtrn->name);
115 setScanState(oldFile, oldLine);
116 if (mapToUse->type != file_type)
118 ERROR("Include file wrong type (expected %s, got %s)\n",
119 XkbcConfigText(file_type), XkbcConfigText(mapToUse->type));
120 ACTION("Include file \"%s\" ignored\n", stmt->file);
123 /* FIXME: we have to check recursive includes here (or somewhere) */
125 mapToUse->compiled = True;
126 *file_rtrn = mapToUse;
127 *merge_rtrn = stmt->merge;
131 /***====================================================================***/
134 ReportNotArray(const char *type, const char *field, const char *name)
136 ERROR("The %s %s field is not an array\n", type, field);
137 ACTION("Ignoring illegal assignment in %s\n", name);
142 ReportShouldBeArray(const char *type, const char *field, const char *name)
144 ERROR("Missing subscript for %s %s\n", type, field);
145 ACTION("Ignoring illegal assignment in %s\n", name);
150 ReportBadType(const char *type, const char *field,
151 const char *name, const char *wanted)
153 ERROR("The %s %s field must be a %s\n", type, field, wanted);
154 ACTION("Ignoring illegal assignment in %s\n", name);
159 ReportBadField(const char *type, const char *field, const char *name)
161 ERROR("Unknown %s field %s in %s\n", type, field, name);
162 ACTION("Ignoring assignment to unknown field in %s\n", name);
166 /***====================================================================***/
169 UseNewField(unsigned field,
170 CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
175 if (oldDefs->defined & field)
177 if (newDefs->defined & field)
179 if (((oldDefs->fileID == newDefs->fileID)
180 && (warningLevel > 0)) || (warningLevel > 9))
184 if (newDefs->merge != MergeAugment)
188 else if (newDefs->defined & field)
194 ClearCommonInfo(CommonInfo * cmn)
198 CommonInfo *this, *next;
199 for (this = cmn; this != NULL; this = next)
209 AddCommonInfo(CommonInfo * old, CommonInfo * new)
214 while (old && old->next)
222 return (char *) first;
227 /***====================================================================***/
229 typedef struct _KeyNameDesc
238 * Find the key with the given name and return its keycode in kc_rtrn.
240 * @param name The 4-letter name of the key as a long.
241 * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
242 * @param use_aliases True if the key aliases should be searched too.
243 * @param create If True and the key is not found, it is added to the
244 * xkb->names at the first free keycode.
245 * @param start_from Keycode to start searching from.
247 * @return True if found, False otherwise.
250 FindNamedKey(struct xkb_desc * xkb,
252 xkb_keycode_t *kc_rtrn,
253 Bool use_aliases, Bool create, int start_from)
257 if (start_from < xkb->min_key_code)
259 start_from = xkb->min_key_code;
261 else if (start_from > xkb->max_key_code)
266 *kc_rtrn = 0; /* some callers rely on this */
267 if (xkb && xkb->names && xkb->names->keys)
269 for (n = start_from; n <= xkb->max_key_code; n++)
272 tmp = KeyNameToLong(xkb->names->keys[n].name);
281 unsigned long new_name;
282 if (FindKeyNameForAlias(xkb, name, &new_name))
283 return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
288 if ((!xkb->names) || (!xkb->names->keys))
290 if (XkbcAllocNames(xkb, XkbKeyNamesMask, 0) != Success)
292 if (warningLevel > 0)
294 WARN("Couldn't allocate key names in FindNamedKey\n");
295 ACTION("Key \"%s\" not automatically created\n",
301 /* Find first unused keycode and store our key here */
302 for (n = xkb->min_key_code; n <= xkb->max_key_code; n++)
304 if (xkb->names->keys[n].name[0] == '\0')
306 char buf[XkbKeyNameLength + 1];
307 LongToKeyName(name, buf);
308 memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength);
318 FindKeyNameForAlias(struct xkb_desc * xkb, unsigned long lname,
319 unsigned long *real_name)
322 char name[XkbKeyNameLength + 1];
324 if (xkb && xkb->names && xkb->names->key_aliases)
326 struct xkb_key_alias * a;
327 a = xkb->names->key_aliases;
328 LongToKeyName(lname, name);
329 name[XkbKeyNameLength] = '\0';
330 for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
332 if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
334 *real_name = KeyNameToLong(a->real);