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, 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 ReportBadIndexType(char *type, char *field, char *name, char *wanted)
156 ERROR("Index for the %s %s field must be a %s\n", type, field, wanted);
157 ACTION("Ignoring assignment to illegal field in %s\n", name);
162 ReportBadField(const char *type, const char *field, const char *name)
164 ERROR("Unknown %s field %s in %s\n", type, field, name);
165 ACTION("Ignoring assignment to unknown field in %s\n", name);
170 ReportMultipleDefs(char *type, char *field, char *name)
172 WARN("Multiple definitions of %s in %s \"%s\"\n", field, type, name);
173 ACTION("Using last definition\n");
177 /***====================================================================***/
180 UseNewField(unsigned field,
181 CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
186 if (oldDefs->defined & field)
188 if (newDefs->defined & field)
190 if (((oldDefs->fileID == newDefs->fileID)
191 && (warningLevel > 0)) || (warningLevel > 9))
195 if (newDefs->merge != MergeAugment)
199 else if (newDefs->defined & field)
205 MergeNewField(unsigned field,
206 CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
208 if ((oldDefs->defined & field) && (newDefs->defined & field))
210 if (((oldDefs->fileID == newDefs->fileID) && (warningLevel > 0)) ||
215 if (newDefs->merge == MergeAugment)
222 ClearCommonInfo(CommonInfo * cmn)
226 CommonInfo *this, *next;
227 for (this = cmn; this != NULL; this = next)
237 AddCommonInfo(CommonInfo * old, CommonInfo * new)
242 while (old && old->next)
250 return (char *) first;
255 /***====================================================================***/
257 typedef struct _KeyNameDesc
265 static KeyNameDesc dfltKeys[] = {
266 {XK_Escape, NoSymbol, "ESC\0"},
267 {XK_quoteleft, XK_asciitilde, "TLDE"},
268 {XK_1, XK_exclam, "AE01"},
269 {XK_2, XK_at, "AE02"},
270 {XK_3, XK_numbersign, "AE03"},
271 {XK_4, XK_dollar, "AE04"},
272 {XK_5, XK_percent, "AE05"},
273 {XK_6, XK_asciicircum, "AE06"},
274 {XK_7, XK_ampersand, "AE07"},
275 {XK_8, XK_asterisk, "AE08"},
276 {XK_9, XK_parenleft, "AE09"},
277 {XK_0, XK_parenright, "AE10"},
278 {XK_minus, XK_underscore, "AE11"},
279 {XK_equal, XK_plus, "AE12"},
280 {XK_BackSpace, NoSymbol, "BKSP"},
281 {XK_Tab, NoSymbol, "TAB\0"},
282 {XK_q, XK_Q, "AD01"},
283 {XK_w, XK_W, "AD02"},
284 {XK_e, XK_E, "AD03"},
285 {XK_r, XK_R, "AD04"},
286 {XK_t, XK_T, "AD05"},
287 {XK_y, XK_Y, "AD06"},
288 {XK_u, XK_U, "AD07"},
289 {XK_i, XK_I, "AD08"},
290 {XK_o, XK_O, "AD09"},
291 {XK_p, XK_P, "AD10"},
292 {XK_bracketleft, XK_braceleft, "AD11"},
293 {XK_bracketright, XK_braceright, "AD12"},
294 {XK_Return, NoSymbol, "RTRN"},
295 {XK_Caps_Lock, NoSymbol, "CAPS"},
296 {XK_a, XK_A, "AC01"},
297 {XK_s, XK_S, "AC02"},
298 {XK_d, XK_D, "AC03"},
299 {XK_f, XK_F, "AC04"},
300 {XK_g, XK_G, "AC05"},
301 {XK_h, XK_H, "AC06"},
302 {XK_j, XK_J, "AC07"},
303 {XK_k, XK_K, "AC08"},
304 {XK_l, XK_L, "AC09"},
305 {XK_semicolon, XK_colon, "AC10"},
306 {XK_quoteright, XK_quotedbl, "AC11"},
307 {XK_Shift_L, NoSymbol, "LFSH"},
308 {XK_z, XK_Z, "AB01"},
309 {XK_x, XK_X, "AB02"},
310 {XK_c, XK_C, "AB03"},
311 {XK_v, XK_V, "AB04"},
312 {XK_b, XK_B, "AB05"},
313 {XK_n, XK_N, "AB06"},
314 {XK_m, XK_M, "AB07"},
315 {XK_comma, XK_less, "AB08"},
316 {XK_period, XK_greater, "AB09"},
317 {XK_slash, XK_question, "AB10"},
318 {XK_backslash, XK_bar, "BKSL"},
319 {XK_Control_L, NoSymbol, "LCTL"},
320 {XK_space, NoSymbol, "SPCE"},
321 {XK_Shift_R, NoSymbol, "RTSH"},
322 {XK_Alt_L, NoSymbol, "LALT"},
323 {XK_space, NoSymbol, "SPCE"},
324 {XK_Control_R, NoSymbol, "RCTL"},
325 {XK_Alt_R, NoSymbol, "RALT"},
326 {XK_F1, NoSymbol, "FK01"},
327 {XK_F2, NoSymbol, "FK02"},
328 {XK_F3, NoSymbol, "FK03"},
329 {XK_F4, NoSymbol, "FK04"},
330 {XK_F5, NoSymbol, "FK05"},
331 {XK_F6, NoSymbol, "FK06"},
332 {XK_F7, NoSymbol, "FK07"},
333 {XK_F8, NoSymbol, "FK08"},
334 {XK_F9, NoSymbol, "FK09"},
335 {XK_F10, NoSymbol, "FK10"},
336 {XK_F11, NoSymbol, "FK11"},
337 {XK_F12, NoSymbol, "FK12"},
338 {XK_Print, NoSymbol, "PRSC"},
339 {XK_Scroll_Lock, NoSymbol, "SCLK"},
340 {XK_Pause, NoSymbol, "PAUS"},
341 {XK_Insert, NoSymbol, "INS\0"},
342 {XK_Home, NoSymbol, "HOME"},
343 {XK_Prior, NoSymbol, "PGUP"},
344 {XK_Delete, NoSymbol, "DELE"},
345 {XK_End, NoSymbol, "END"},
346 {XK_Next, NoSymbol, "PGDN"},
347 {XK_Up, NoSymbol, "UP\0\0"},
348 {XK_Left, NoSymbol, "LEFT"},
349 {XK_Down, NoSymbol, "DOWN"},
350 {XK_Right, NoSymbol, "RGHT"},
351 {XK_Num_Lock, NoSymbol, "NMLK"},
352 {XK_KP_Divide, NoSymbol, "KPDV"},
353 {XK_KP_Multiply, NoSymbol, "KPMU"},
354 {XK_KP_Subtract, NoSymbol, "KPSU"},
355 {NoSymbol, XK_KP_7, "KP7\0"},
356 {NoSymbol, XK_KP_8, "KP8\0"},
357 {NoSymbol, XK_KP_9, "KP9\0"},
358 {XK_KP_Add, NoSymbol, "KPAD"},
359 {NoSymbol, XK_KP_4, "KP4\0"},
360 {NoSymbol, XK_KP_5, "KP5\0"},
361 {NoSymbol, XK_KP_6, "KP6\0"},
362 {NoSymbol, XK_KP_1, "KP1\0"},
363 {NoSymbol, XK_KP_2, "KP2\0"},
364 {NoSymbol, XK_KP_3, "KP3\0"},
365 {XK_KP_Enter, NoSymbol, "KPEN"},
366 {NoSymbol, XK_KP_0, "KP0\0"},
367 {XK_KP_Delete, NoSymbol, "KPDL"},
368 {XK_less, XK_greater, "LSGT"},
369 {XK_KP_Separator, NoSymbol, "KPCO"},
370 {XK_Find, NoSymbol, "FIND"},
371 {NoSymbol, NoSymbol, "\0\0\0\0"}
375 ComputeKbdDefaults(XkbcDescPtr xkb)
378 register int i, tmp, nUnknown;
382 if ((xkb->names == NULL) || (xkb->names->keys == NULL))
384 if ((rtrn = XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 0)) != Success)
387 for (name = dfltKeys; (name->name[0] != '\0'); name++)
392 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
394 tmp = XkbKeyNumSyms(xkb, i);
395 if ((xkb->names->keys[i].name[0] == '\0') && (tmp > 0))
397 tmp = XkbKeyGroupsWidth(xkb, i);
398 syms = XkbKeySymsPtr(xkb, i);
399 for (name = dfltKeys; (name->name[0] != '\0'); name++)
402 if (((name->level1 != syms[0])
403 && (name->level1 != NoSymbol))
404 || ((name->level2 != NoSymbol) && (tmp < 2))
405 || ((name->level2 != syms[1])
406 && (name->level2 != NoSymbol)))
414 memcpy(xkb->names->keys[i].name, name->name,
420 if (warningLevel > 2)
423 ("Several keys match pattern for %s\n",
424 XkbcKeyNameText(name->name));
425 ACTION("Using <U%03d> for key %d\n",
428 sprintf(xkb->names->keys[i].name, "U%03d",
434 if (xkb->names->keys[i].name[0] == '\0')
436 if (warningLevel > 2)
438 WARN("Key %d does not match any defaults\n", i);
439 ACTION("Using name <U%03d>\n", nUnknown);
440 sprintf(xkb->names->keys[i].name, "U%03d", nUnknown++);
449 * Find the key with the given name and return its keycode in kc_rtrn.
451 * @param name The 4-letter name of the key as a long.
452 * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
453 * @param use_aliases True if the key aliases should be searched too.
454 * @param create If True and the key is not found, it is added to the
455 * xkb->names at the first free keycode.
456 * @param start_from Keycode to start searching from.
458 * @return True if found, False otherwise.
461 FindNamedKey(XkbcDescPtr xkb,
463 unsigned int *kc_rtrn,
464 Bool use_aliases, Bool create, int start_from)
468 if (start_from < xkb->min_key_code)
470 start_from = xkb->min_key_code;
472 else if (start_from > xkb->max_key_code)
477 *kc_rtrn = 0; /* some callers rely on this */
478 if (xkb && xkb->names && xkb->names->keys)
480 for (n = start_from; n <= xkb->max_key_code; n++)
483 tmp = KeyNameToLong(xkb->names->keys[n].name);
492 unsigned long new_name;
493 if (FindKeyNameForAlias(xkb, name, &new_name))
494 return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
499 if ((!xkb->names) || (!xkb->names->keys))
501 if (xkb->min_key_code < XkbMinLegalKeyCode)
503 xkb->min_key_code = XkbMinLegalKeyCode;
504 xkb->max_key_code = XkbMaxLegalKeyCode;
506 if (XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 0) != Success)
508 if (warningLevel > 0)
510 WARN("Couldn't allocate key names in FindNamedKey\n");
511 ACTION("Key \"%s\" not automatically created\n",
517 /* Find first unused keycode and store our key here */
518 for (n = xkb->min_key_code; n <= xkb->max_key_code; n++)
520 if (xkb->names->keys[n].name[0] == '\0')
522 char buf[XkbKeyNameLength + 1];
523 LongToKeyName(name, buf);
524 memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength);
534 FindKeyNameForAlias(XkbcDescPtr xkb, unsigned long lname,
535 unsigned long *real_name)
538 char name[XkbKeyNameLength + 1];
540 if (xkb && xkb->geom && xkb->geom->key_aliases)
543 a = xkb->geom->key_aliases;
544 LongToKeyName(lname, name);
545 name[XkbKeyNameLength] = '\0';
546 for (i = 0; i < xkb->geom->num_key_aliases; i++, a++)
548 if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
550 *real_name = KeyNameToLong(a->real);
555 if (xkb && xkb->names && xkb->names->key_aliases)
558 a = xkb->names->key_aliases;
559 LongToKeyName(lname, name);
560 name[XkbKeyNameLength] = '\0';
561 for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
563 if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
565 *real_name = KeyNameToLong(a->real);