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 ********************************************************/
34 #include <X11/keysym.h>
35 #include "parseutils.h"
37 /***====================================================================***/
40 * Open the file given in the include statement and parse it's content.
41 * If the statement defines a specific map to use, this map is returned in
42 * file_rtrn. Otherwise, the default map is returned.
44 * @param stmt The include statement, specifying the file name to look for.
45 * @param file_type Type of file (XkmKeyNamesIdx, etc.)
46 * @param file_rtrn Returns the key map to be used.
47 * @param merge_rtrn Always returns stmt->merge.
49 * @return True on success or False otherwise.
52 ProcessIncludeFile(IncludeStmt * stmt,
54 XkbFile ** file_rtrn, unsigned *merge_rtrn)
57 XkbFile *rtrn, *mapToUse;
58 char oldFile[1024] = {0};
59 int oldLine = lineNum;
61 rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path);
64 /* file not in cache, open it, parse it and store it in cache for next
66 file = XkbFindFileInPath(stmt->file, file_type, &stmt->path);
69 ERROR("Can't find file \"%s\" for %s include\n", stmt->file,
70 XkbDirectoryForInclude(file_type));
73 strcpy(oldFile, scanFile);
75 setScanState(stmt->file, 1);
77 INFO("About to parse include file %s\n", stmt->file);
79 if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
81 setScanState(oldFile, oldLine);
82 ERROR("Error interpreting include file \"%s\"\n", stmt->file);
87 XkbAddFileToCache(stmt->file, file_type, stmt->path, rtrn);
90 if (stmt->map != NULL)
92 while ((mapToUse) && ((!uStringEqual(mapToUse->name, stmt->map)) ||
93 (mapToUse->type != file_type)))
95 mapToUse = (XkbFile *) mapToUse->common.next;
99 ERROR("No %s named \"%s\" in the include file \"%s\"\n",
100 XkbcConfigText(file_type), stmt->map, stmt->file);
104 else if ((rtrn->common.next != NULL) && (warningLevel > 5))
106 WARN("No map in include statement, but \"%s\" contains several\n",
108 ACTION("Using first defined map, \"%s\"\n", rtrn->name);
110 setScanState(oldFile, oldLine);
111 if (mapToUse->type != file_type)
113 ERROR("Include file wrong type (expected %s, got %s)\n",
114 XkbcConfigText(file_type), XkbcConfigText(mapToUse->type));
115 ACTION("Include file \"%s\" ignored\n", stmt->file);
118 /* FIXME: we have to check recursive includes here (or somewhere) */
120 mapToUse->compiled = True;
121 *file_rtrn = mapToUse;
122 *merge_rtrn = stmt->merge;
126 /***====================================================================***/
129 ReportNotArray(const char *type, const char *field, const char *name)
131 ERROR("The %s %s field is not an array\n", type, field);
132 ACTION("Ignoring illegal assignment in %s\n", name);
137 ReportShouldBeArray(const char *type, const char *field, const char *name)
139 ERROR("Missing subscript for %s %s\n", type, field);
140 ACTION("Ignoring illegal assignment in %s\n", name);
145 ReportBadType(const char *type, const char *field,
146 const char *name, const char *wanted)
148 ERROR("The %s %s field must be a %s\n", type, field, wanted);
149 ACTION("Ignoring illegal assignment in %s\n", name);
154 ReportBadField(const char *type, const char *field, const char *name)
156 ERROR("Unknown %s field %s in %s\n", type, field, name);
157 ACTION("Ignoring assignment to unknown field in %s\n", name);
161 /***====================================================================***/
164 UseNewField(unsigned field,
165 CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
170 if (oldDefs->defined & field)
172 if (newDefs->defined & field)
174 if (((oldDefs->fileID == newDefs->fileID)
175 && (warningLevel > 0)) || (warningLevel > 9))
179 if (newDefs->merge != MergeAugment)
183 else if (newDefs->defined & field)
189 ClearCommonInfo(CommonInfo * cmn)
193 CommonInfo *this, *next;
194 for (this = cmn; this != NULL; this = next)
204 AddCommonInfo(CommonInfo * old, CommonInfo * new)
209 while (old && old->next)
217 return (char *) first;
222 /***====================================================================***/
224 typedef struct _KeyNameDesc
233 * Find the key with the given name and return its keycode in kc_rtrn.
235 * @param name The 4-letter name of the key as a long.
236 * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
237 * @param use_aliases True if the key aliases should be searched too.
238 * @param create If True and the key is not found, it is added to the
239 * xkb->names at the first free keycode.
240 * @param start_from Keycode to start searching from.
242 * @return True if found, False otherwise.
245 FindNamedKey(struct xkb_desc * xkb,
247 unsigned int *kc_rtrn,
248 Bool use_aliases, Bool create, int start_from)
252 if (start_from < xkb->min_key_code)
254 start_from = xkb->min_key_code;
256 else if (start_from > xkb->max_key_code)
261 *kc_rtrn = 0; /* some callers rely on this */
262 if (xkb && xkb->names && xkb->names->keys)
264 for (n = start_from; n <= xkb->max_key_code; n++)
267 tmp = KeyNameToLong(xkb->names->keys[n].name);
276 unsigned long new_name;
277 if (FindKeyNameForAlias(xkb, name, &new_name))
278 return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
283 if ((!xkb->names) || (!xkb->names->keys))
285 if (xkb->min_key_code < XkbMinLegalKeyCode)
287 xkb->min_key_code = XkbMinLegalKeyCode;
288 xkb->max_key_code = XkbMaxLegalKeyCode;
290 if (XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 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->geom && xkb->geom->key_aliases)
326 struct xkb_key_alias * a;
327 a = xkb->geom->key_aliases;
328 LongToKeyName(lname, name);
329 name[XkbKeyNameLength] = '\0';
330 for (i = 0; i < xkb->geom->num_key_aliases; i++, a++)
332 if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
334 *real_name = KeyNameToLong(a->real);
339 if (xkb && xkb->names && xkb->names->key_aliases)
341 struct xkb_key_alias * a;
342 a = xkb->names->key_aliases;
343 LongToKeyName(lname, name);
344 name[XkbKeyNameLength] = '\0';
345 for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
347 if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
349 *real_name = KeyNameToLong(a->real);