2 * Copyright 2009 Dan Nicholson
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * Except as contained in this notice, the names of the authors or their
22 * institutions shall not be used in advertising or otherwise to promote the
23 * sale, use or other dealings in this Software without prior written
24 * authorization from the authors.
27 #include "xkbcomp-priv.h"
31 typedef bool (*compile_file_fn)(XkbFile *file,
32 struct xkb_keymap *keymap,
33 enum merge_mode merge);
35 static const compile_file_fn compile_file_fns[LAST_KEYMAP_FILE_TYPE + 1] = {
36 [FILE_TYPE_KEYCODES] = CompileKeycodes,
37 [FILE_TYPE_TYPES] = CompileKeyTypes,
38 [FILE_TYPE_COMPAT] = CompileCompatMap,
39 [FILE_TYPE_SYMBOLS] = CompileSymbols,
42 static struct xkb_keymap *
43 compile_keymap_file(struct xkb_context *ctx, XkbFile *file)
46 const char *main_name;
47 struct xkb_keymap *keymap;
48 XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL };
49 enum xkb_file_type type;
51 keymap = xkb_map_new(ctx);
55 main_name = file->name ? file->name : "(unnamed)";
57 if (file->file_type != FILE_TYPE_KEYMAP) {
58 log_err(ctx, "Cannot compile a %s file alone into a keymap\n",
59 FileTypeText(file->file_type));
63 /* Collect section files and check for duplicates. */
64 for (file = (XkbFile *) file->defs; file;
65 file = (XkbFile *) file->common.next) {
66 if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
67 file->file_type > LAST_KEYMAP_FILE_TYPE) {
68 log_err(ctx, "Cannot define %s in a keymap file\n",
69 FileTypeText(file->file_type));
73 if (files[file->file_type]) {
75 "More than one %s section in keymap file; "
76 "All sections after the first ignored\n",
77 FileTypeText(file->file_type));
83 file->topName = strdup(main_name);
86 files[file->file_type] = file;
90 * Check that all required section were provided.
91 * Report everything before failing.
94 for (type = FIRST_KEYMAP_FILE_TYPE;
95 type <= LAST_KEYMAP_FILE_TYPE;
97 if (files[type] == NULL) {
98 log_err(ctx, "Required section %s missing from keymap\n",
106 /* Compile sections. */
107 for (type = FIRST_KEYMAP_FILE_TYPE;
108 type <= LAST_KEYMAP_FILE_TYPE;
110 log_dbg(ctx, "Compiling %s \"%s\"\n",
111 FileTypeText(type), files[type]->topName);
112 ok = compile_file_fns[type](files[type], keymap, MERGE_OVERRIDE);
114 log_err(ctx, "Failed to compile %s\n", FileTypeText(type));
119 ok = UpdateModifiersFromCompat(keymap);
126 log_err(ctx, "Failed to compile keymap\n");
127 xkb_map_unref(keymap);
131 XKB_EXPORT struct xkb_keymap *
132 xkb_map_new_from_names(struct xkb_context *ctx,
133 const struct xkb_rule_names *rmlvo_in,
134 enum xkb_map_compile_flags flags)
137 struct xkb_component_names kccgst;
138 struct xkb_rule_names rmlvo = *rmlvo_in;
140 struct xkb_keymap *keymap;
142 if (isempty(rmlvo.rules))
143 rmlvo.rules = DEFAULT_XKB_RULES;
144 if (isempty(rmlvo.model))
145 rmlvo.model = DEFAULT_XKB_MODEL;
146 if (isempty(rmlvo.layout))
147 rmlvo.layout = DEFAULT_XKB_LAYOUT;
149 ok = xkb_components_from_rules(ctx, &rmlvo, &kccgst);
152 "Couldn't look up rules '%s', model '%s', layout '%s', "
153 "variant '%s', options '%s'\n",
154 rmlvo.rules, rmlvo.model, rmlvo.layout, rmlvo.variant,
159 file = XkbFileFromComponents(ctx, &kccgst);
161 free(kccgst.keycodes);
164 free(kccgst.symbols);
168 "Failed to generate parsed XKB file from components\n");
172 keymap = compile_keymap_file(ctx, file);
177 XKB_EXPORT struct xkb_keymap *
178 xkb_map_new_from_string(struct xkb_context *ctx,
180 enum xkb_keymap_format format,
181 enum xkb_map_compile_flags flags)
185 struct xkb_keymap *keymap;
187 if (format != XKB_KEYMAP_FORMAT_TEXT_V1) {
188 log_err(ctx, "Unsupported keymap format %d\n", format);
193 log_err(ctx, "No string specified to generate XKB keymap\n");
197 ok = XkbParseString(ctx, string, "input", &file);
199 log_err(ctx, "Failed to parse input xkb file\n");
203 keymap = compile_keymap_file(ctx, file);
208 XKB_EXPORT struct xkb_keymap *
209 xkb_map_new_from_file(struct xkb_context *ctx,
211 enum xkb_keymap_format format,
212 enum xkb_map_compile_flags flags)
216 struct xkb_keymap *keymap;
218 if (format != XKB_KEYMAP_FORMAT_TEXT_V1) {
219 log_err(ctx, "Unsupported keymap format %d\n", format);
224 log_err(ctx, "No file specified to generate XKB keymap\n");
228 ok = XkbParseFile(ctx, file, "(unknown file)", &xkb_file);
230 log_err(ctx, "Failed to parse input xkb file\n");
234 keymap = compile_keymap_file(ctx, xkb_file);
235 FreeXkbFile(xkb_file);