1*2b949d04SAndroid Build Coastguard Worker /*
2*2b949d04SAndroid Build Coastguard Worker * Copyright © 2018 Red Hat, Inc.
3*2b949d04SAndroid Build Coastguard Worker *
4*2b949d04SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*2b949d04SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*2b949d04SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*2b949d04SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*2b949d04SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*2b949d04SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*2b949d04SAndroid Build Coastguard Worker *
11*2b949d04SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*2b949d04SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*2b949d04SAndroid Build Coastguard Worker * Software.
14*2b949d04SAndroid Build Coastguard Worker *
15*2b949d04SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*2b949d04SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*2b949d04SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*2b949d04SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*2b949d04SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*2b949d04SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*2b949d04SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
22*2b949d04SAndroid Build Coastguard Worker */
23*2b949d04SAndroid Build Coastguard Worker
24*2b949d04SAndroid Build Coastguard Worker #include "config.h"
25*2b949d04SAndroid Build Coastguard Worker
26*2b949d04SAndroid Build Coastguard Worker #include <assert.h>
27*2b949d04SAndroid Build Coastguard Worker #include <errno.h>
28*2b949d04SAndroid Build Coastguard Worker #include <getopt.h>
29*2b949d04SAndroid Build Coastguard Worker #include <stdio.h>
30*2b949d04SAndroid Build Coastguard Worker #include <stdbool.h>
31*2b949d04SAndroid Build Coastguard Worker #include <stdlib.h>
32*2b949d04SAndroid Build Coastguard Worker #include <string.h>
33*2b949d04SAndroid Build Coastguard Worker
34*2b949d04SAndroid Build Coastguard Worker #include "xkbcommon/xkbcommon.h"
35*2b949d04SAndroid Build Coastguard Worker #if ENABLE_PRIVATE_APIS
36*2b949d04SAndroid Build Coastguard Worker #include "xkbcomp/xkbcomp-priv.h"
37*2b949d04SAndroid Build Coastguard Worker #include "xkbcomp/rules.h"
38*2b949d04SAndroid Build Coastguard Worker #endif
39*2b949d04SAndroid Build Coastguard Worker #include "tools-common.h"
40*2b949d04SAndroid Build Coastguard Worker
41*2b949d04SAndroid Build Coastguard Worker #define DEFAULT_INCLUDE_PATH_PLACEHOLDER "__defaults__"
42*2b949d04SAndroid Build Coastguard Worker
43*2b949d04SAndroid Build Coastguard Worker static bool verbose = false;
44*2b949d04SAndroid Build Coastguard Worker static enum output_format {
45*2b949d04SAndroid Build Coastguard Worker FORMAT_RMLVO,
46*2b949d04SAndroid Build Coastguard Worker FORMAT_KEYMAP,
47*2b949d04SAndroid Build Coastguard Worker FORMAT_KCCGST,
48*2b949d04SAndroid Build Coastguard Worker FORMAT_KEYMAP_FROM_XKB,
49*2b949d04SAndroid Build Coastguard Worker } output_format = FORMAT_KEYMAP;
50*2b949d04SAndroid Build Coastguard Worker static const char *includes[64];
51*2b949d04SAndroid Build Coastguard Worker static size_t num_includes = 0;
52*2b949d04SAndroid Build Coastguard Worker
53*2b949d04SAndroid Build Coastguard Worker static void
usage(char ** argv)54*2b949d04SAndroid Build Coastguard Worker usage(char **argv)
55*2b949d04SAndroid Build Coastguard Worker {
56*2b949d04SAndroid Build Coastguard Worker printf("Usage: %s [OPTIONS]\n"
57*2b949d04SAndroid Build Coastguard Worker "\n"
58*2b949d04SAndroid Build Coastguard Worker "Compile the given RMLVO to a keymap and print it\n"
59*2b949d04SAndroid Build Coastguard Worker "\n"
60*2b949d04SAndroid Build Coastguard Worker "Options:\n"
61*2b949d04SAndroid Build Coastguard Worker " --verbose\n"
62*2b949d04SAndroid Build Coastguard Worker " Enable verbose debugging output\n"
63*2b949d04SAndroid Build Coastguard Worker #if ENABLE_PRIVATE_APIS
64*2b949d04SAndroid Build Coastguard Worker " --kccgst\n"
65*2b949d04SAndroid Build Coastguard Worker " Print a keymap which only includes the KcCGST component names instead of the full keymap\n"
66*2b949d04SAndroid Build Coastguard Worker #endif
67*2b949d04SAndroid Build Coastguard Worker " --rmlvo\n"
68*2b949d04SAndroid Build Coastguard Worker " Print the full RMLVO with the defaults filled in for missing elements\n"
69*2b949d04SAndroid Build Coastguard Worker " --from-xkb\n"
70*2b949d04SAndroid Build Coastguard Worker " Load the XKB file from stdin, ignore RMLVO options.\n"
71*2b949d04SAndroid Build Coastguard Worker #if ENABLE_PRIVATE_APIS
72*2b949d04SAndroid Build Coastguard Worker " This option must not be used with --kccgst.\n"
73*2b949d04SAndroid Build Coastguard Worker #endif
74*2b949d04SAndroid Build Coastguard Worker " --include\n"
75*2b949d04SAndroid Build Coastguard Worker " Add the given path to the include path list. This option is\n"
76*2b949d04SAndroid Build Coastguard Worker " order-dependent, include paths given first are searched first.\n"
77*2b949d04SAndroid Build Coastguard Worker " If an include path is given, the default include path list is\n"
78*2b949d04SAndroid Build Coastguard Worker " not used. Use --include-defaults to add the default include\n"
79*2b949d04SAndroid Build Coastguard Worker " paths\n"
80*2b949d04SAndroid Build Coastguard Worker " --include-defaults\n"
81*2b949d04SAndroid Build Coastguard Worker " Add the default set of include directories.\n"
82*2b949d04SAndroid Build Coastguard Worker " This option is order-dependent, include paths given first\n"
83*2b949d04SAndroid Build Coastguard Worker " are searched first.\n"
84*2b949d04SAndroid Build Coastguard Worker "\n"
85*2b949d04SAndroid Build Coastguard Worker "XKB-specific options:\n"
86*2b949d04SAndroid Build Coastguard Worker " --rules <rules>\n"
87*2b949d04SAndroid Build Coastguard Worker " The XKB ruleset (default: '%s')\n"
88*2b949d04SAndroid Build Coastguard Worker " --model <model>\n"
89*2b949d04SAndroid Build Coastguard Worker " The XKB model (default: '%s')\n"
90*2b949d04SAndroid Build Coastguard Worker " --layout <layout>\n"
91*2b949d04SAndroid Build Coastguard Worker " The XKB layout (default: '%s')\n"
92*2b949d04SAndroid Build Coastguard Worker " --variant <variant>\n"
93*2b949d04SAndroid Build Coastguard Worker " The XKB layout variant (default: '%s')\n"
94*2b949d04SAndroid Build Coastguard Worker " --options <options>\n"
95*2b949d04SAndroid Build Coastguard Worker " The XKB options (default: '%s')\n"
96*2b949d04SAndroid Build Coastguard Worker "\n",
97*2b949d04SAndroid Build Coastguard Worker argv[0], DEFAULT_XKB_RULES,
98*2b949d04SAndroid Build Coastguard Worker DEFAULT_XKB_MODEL, DEFAULT_XKB_LAYOUT,
99*2b949d04SAndroid Build Coastguard Worker DEFAULT_XKB_VARIANT ? DEFAULT_XKB_VARIANT : "<none>",
100*2b949d04SAndroid Build Coastguard Worker DEFAULT_XKB_OPTIONS ? DEFAULT_XKB_OPTIONS : "<none>");
101*2b949d04SAndroid Build Coastguard Worker }
102*2b949d04SAndroid Build Coastguard Worker
103*2b949d04SAndroid Build Coastguard Worker static bool
parse_options(int argc,char ** argv,struct xkb_rule_names * names)104*2b949d04SAndroid Build Coastguard Worker parse_options(int argc, char **argv, struct xkb_rule_names *names)
105*2b949d04SAndroid Build Coastguard Worker {
106*2b949d04SAndroid Build Coastguard Worker enum options {
107*2b949d04SAndroid Build Coastguard Worker OPT_VERBOSE,
108*2b949d04SAndroid Build Coastguard Worker OPT_KCCGST,
109*2b949d04SAndroid Build Coastguard Worker OPT_RMLVO,
110*2b949d04SAndroid Build Coastguard Worker OPT_FROM_XKB,
111*2b949d04SAndroid Build Coastguard Worker OPT_INCLUDE,
112*2b949d04SAndroid Build Coastguard Worker OPT_INCLUDE_DEFAULTS,
113*2b949d04SAndroid Build Coastguard Worker OPT_RULES,
114*2b949d04SAndroid Build Coastguard Worker OPT_MODEL,
115*2b949d04SAndroid Build Coastguard Worker OPT_LAYOUT,
116*2b949d04SAndroid Build Coastguard Worker OPT_VARIANT,
117*2b949d04SAndroid Build Coastguard Worker OPT_OPTION,
118*2b949d04SAndroid Build Coastguard Worker };
119*2b949d04SAndroid Build Coastguard Worker static struct option opts[] = {
120*2b949d04SAndroid Build Coastguard Worker {"help", no_argument, 0, 'h'},
121*2b949d04SAndroid Build Coastguard Worker {"verbose", no_argument, 0, OPT_VERBOSE},
122*2b949d04SAndroid Build Coastguard Worker #if ENABLE_PRIVATE_APIS
123*2b949d04SAndroid Build Coastguard Worker {"kccgst", no_argument, 0, OPT_KCCGST},
124*2b949d04SAndroid Build Coastguard Worker #endif
125*2b949d04SAndroid Build Coastguard Worker {"rmlvo", no_argument, 0, OPT_RMLVO},
126*2b949d04SAndroid Build Coastguard Worker {"from-xkb", no_argument, 0, OPT_FROM_XKB},
127*2b949d04SAndroid Build Coastguard Worker {"include", required_argument, 0, OPT_INCLUDE},
128*2b949d04SAndroid Build Coastguard Worker {"include-defaults", no_argument, 0, OPT_INCLUDE_DEFAULTS},
129*2b949d04SAndroid Build Coastguard Worker {"rules", required_argument, 0, OPT_RULES},
130*2b949d04SAndroid Build Coastguard Worker {"model", required_argument, 0, OPT_MODEL},
131*2b949d04SAndroid Build Coastguard Worker {"layout", required_argument, 0, OPT_LAYOUT},
132*2b949d04SAndroid Build Coastguard Worker {"variant", required_argument, 0, OPT_VARIANT},
133*2b949d04SAndroid Build Coastguard Worker {"options", required_argument, 0, OPT_OPTION},
134*2b949d04SAndroid Build Coastguard Worker {0, 0, 0, 0},
135*2b949d04SAndroid Build Coastguard Worker };
136*2b949d04SAndroid Build Coastguard Worker
137*2b949d04SAndroid Build Coastguard Worker while (1) {
138*2b949d04SAndroid Build Coastguard Worker int c;
139*2b949d04SAndroid Build Coastguard Worker int option_index = 0;
140*2b949d04SAndroid Build Coastguard Worker c = getopt_long(argc, argv, "h", opts, &option_index);
141*2b949d04SAndroid Build Coastguard Worker if (c == -1)
142*2b949d04SAndroid Build Coastguard Worker break;
143*2b949d04SAndroid Build Coastguard Worker
144*2b949d04SAndroid Build Coastguard Worker switch (c) {
145*2b949d04SAndroid Build Coastguard Worker case 'h':
146*2b949d04SAndroid Build Coastguard Worker usage(argv);
147*2b949d04SAndroid Build Coastguard Worker exit(0);
148*2b949d04SAndroid Build Coastguard Worker case OPT_VERBOSE:
149*2b949d04SAndroid Build Coastguard Worker verbose = true;
150*2b949d04SAndroid Build Coastguard Worker break;
151*2b949d04SAndroid Build Coastguard Worker case OPT_KCCGST:
152*2b949d04SAndroid Build Coastguard Worker output_format = FORMAT_KCCGST;
153*2b949d04SAndroid Build Coastguard Worker break;
154*2b949d04SAndroid Build Coastguard Worker case OPT_RMLVO:
155*2b949d04SAndroid Build Coastguard Worker output_format = FORMAT_RMLVO;
156*2b949d04SAndroid Build Coastguard Worker break;
157*2b949d04SAndroid Build Coastguard Worker case OPT_FROM_XKB:
158*2b949d04SAndroid Build Coastguard Worker output_format = FORMAT_KEYMAP_FROM_XKB;
159*2b949d04SAndroid Build Coastguard Worker break;
160*2b949d04SAndroid Build Coastguard Worker case OPT_INCLUDE:
161*2b949d04SAndroid Build Coastguard Worker if (num_includes >= ARRAY_SIZE(includes)) {
162*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "error: too many includes\n");
163*2b949d04SAndroid Build Coastguard Worker exit(EXIT_INVALID_USAGE);
164*2b949d04SAndroid Build Coastguard Worker }
165*2b949d04SAndroid Build Coastguard Worker includes[num_includes++] = optarg;
166*2b949d04SAndroid Build Coastguard Worker break;
167*2b949d04SAndroid Build Coastguard Worker case OPT_INCLUDE_DEFAULTS:
168*2b949d04SAndroid Build Coastguard Worker if (num_includes >= ARRAY_SIZE(includes)) {
169*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "error: too many includes\n");
170*2b949d04SAndroid Build Coastguard Worker exit(EXIT_INVALID_USAGE);
171*2b949d04SAndroid Build Coastguard Worker }
172*2b949d04SAndroid Build Coastguard Worker includes[num_includes++] = DEFAULT_INCLUDE_PATH_PLACEHOLDER;
173*2b949d04SAndroid Build Coastguard Worker break;
174*2b949d04SAndroid Build Coastguard Worker case OPT_RULES:
175*2b949d04SAndroid Build Coastguard Worker names->rules = optarg;
176*2b949d04SAndroid Build Coastguard Worker break;
177*2b949d04SAndroid Build Coastguard Worker case OPT_MODEL:
178*2b949d04SAndroid Build Coastguard Worker names->model = optarg;
179*2b949d04SAndroid Build Coastguard Worker break;
180*2b949d04SAndroid Build Coastguard Worker case OPT_LAYOUT:
181*2b949d04SAndroid Build Coastguard Worker names->layout = optarg;
182*2b949d04SAndroid Build Coastguard Worker break;
183*2b949d04SAndroid Build Coastguard Worker case OPT_VARIANT:
184*2b949d04SAndroid Build Coastguard Worker names->variant = optarg;
185*2b949d04SAndroid Build Coastguard Worker break;
186*2b949d04SAndroid Build Coastguard Worker case OPT_OPTION:
187*2b949d04SAndroid Build Coastguard Worker names->options = optarg;
188*2b949d04SAndroid Build Coastguard Worker break;
189*2b949d04SAndroid Build Coastguard Worker default:
190*2b949d04SAndroid Build Coastguard Worker usage(argv);
191*2b949d04SAndroid Build Coastguard Worker exit(EXIT_INVALID_USAGE);
192*2b949d04SAndroid Build Coastguard Worker }
193*2b949d04SAndroid Build Coastguard Worker
194*2b949d04SAndroid Build Coastguard Worker }
195*2b949d04SAndroid Build Coastguard Worker
196*2b949d04SAndroid Build Coastguard Worker return true;
197*2b949d04SAndroid Build Coastguard Worker }
198*2b949d04SAndroid Build Coastguard Worker
199*2b949d04SAndroid Build Coastguard Worker static bool
print_rmlvo(struct xkb_context * ctx,const struct xkb_rule_names * rmlvo)200*2b949d04SAndroid Build Coastguard Worker print_rmlvo(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
201*2b949d04SAndroid Build Coastguard Worker {
202*2b949d04SAndroid Build Coastguard Worker printf("rules: \"%s\"\nmodel: \"%s\"\nlayout: \"%s\"\nvariant: \"%s\"\noptions: \"%s\"\n",
203*2b949d04SAndroid Build Coastguard Worker rmlvo->rules, rmlvo->model, rmlvo->layout,
204*2b949d04SAndroid Build Coastguard Worker rmlvo->variant ? rmlvo->variant : "",
205*2b949d04SAndroid Build Coastguard Worker rmlvo->options ? rmlvo->options : "");
206*2b949d04SAndroid Build Coastguard Worker return true;
207*2b949d04SAndroid Build Coastguard Worker }
208*2b949d04SAndroid Build Coastguard Worker
209*2b949d04SAndroid Build Coastguard Worker static bool
print_kccgst(struct xkb_context * ctx,const struct xkb_rule_names * rmlvo)210*2b949d04SAndroid Build Coastguard Worker print_kccgst(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
211*2b949d04SAndroid Build Coastguard Worker {
212*2b949d04SAndroid Build Coastguard Worker #if ENABLE_PRIVATE_APIS
213*2b949d04SAndroid Build Coastguard Worker struct xkb_component_names kccgst;
214*2b949d04SAndroid Build Coastguard Worker
215*2b949d04SAndroid Build Coastguard Worker if (!xkb_components_from_rules(ctx, rmlvo, &kccgst))
216*2b949d04SAndroid Build Coastguard Worker return false;
217*2b949d04SAndroid Build Coastguard Worker
218*2b949d04SAndroid Build Coastguard Worker printf("xkb_keymap {\n"
219*2b949d04SAndroid Build Coastguard Worker " xkb_keycodes { include \"%s\" };\n"
220*2b949d04SAndroid Build Coastguard Worker " xkb_types { include \"%s\" };\n"
221*2b949d04SAndroid Build Coastguard Worker " xkb_compat { include \"%s\" };\n"
222*2b949d04SAndroid Build Coastguard Worker " xkb_symbols { include \"%s\" };\n"
223*2b949d04SAndroid Build Coastguard Worker "};\n",
224*2b949d04SAndroid Build Coastguard Worker kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols);
225*2b949d04SAndroid Build Coastguard Worker free(kccgst.keycodes);
226*2b949d04SAndroid Build Coastguard Worker free(kccgst.types);
227*2b949d04SAndroid Build Coastguard Worker free(kccgst.compat);
228*2b949d04SAndroid Build Coastguard Worker free(kccgst.symbols);
229*2b949d04SAndroid Build Coastguard Worker
230*2b949d04SAndroid Build Coastguard Worker return true;
231*2b949d04SAndroid Build Coastguard Worker #else
232*2b949d04SAndroid Build Coastguard Worker return false;
233*2b949d04SAndroid Build Coastguard Worker #endif
234*2b949d04SAndroid Build Coastguard Worker }
235*2b949d04SAndroid Build Coastguard Worker
236*2b949d04SAndroid Build Coastguard Worker static bool
print_keymap(struct xkb_context * ctx,const struct xkb_rule_names * rmlvo)237*2b949d04SAndroid Build Coastguard Worker print_keymap(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
238*2b949d04SAndroid Build Coastguard Worker {
239*2b949d04SAndroid Build Coastguard Worker struct xkb_keymap *keymap;
240*2b949d04SAndroid Build Coastguard Worker
241*2b949d04SAndroid Build Coastguard Worker keymap = xkb_keymap_new_from_names(ctx, rmlvo, XKB_KEYMAP_COMPILE_NO_FLAGS);
242*2b949d04SAndroid Build Coastguard Worker if (keymap == NULL)
243*2b949d04SAndroid Build Coastguard Worker return false;
244*2b949d04SAndroid Build Coastguard Worker
245*2b949d04SAndroid Build Coastguard Worker printf("%s\n", xkb_keymap_get_as_string(keymap,
246*2b949d04SAndroid Build Coastguard Worker XKB_KEYMAP_FORMAT_TEXT_V1));
247*2b949d04SAndroid Build Coastguard Worker xkb_keymap_unref(keymap);
248*2b949d04SAndroid Build Coastguard Worker return true;
249*2b949d04SAndroid Build Coastguard Worker }
250*2b949d04SAndroid Build Coastguard Worker
251*2b949d04SAndroid Build Coastguard Worker static bool
print_keymap_from_file(struct xkb_context * ctx)252*2b949d04SAndroid Build Coastguard Worker print_keymap_from_file(struct xkb_context *ctx)
253*2b949d04SAndroid Build Coastguard Worker {
254*2b949d04SAndroid Build Coastguard Worker struct xkb_keymap *keymap = NULL;
255*2b949d04SAndroid Build Coastguard Worker char *keymap_string = NULL;
256*2b949d04SAndroid Build Coastguard Worker FILE *file = NULL;
257*2b949d04SAndroid Build Coastguard Worker bool success = false;
258*2b949d04SAndroid Build Coastguard Worker
259*2b949d04SAndroid Build Coastguard Worker file = tmpfile();
260*2b949d04SAndroid Build Coastguard Worker if (!file) {
261*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Failed to create tmpfile\n");
262*2b949d04SAndroid Build Coastguard Worker goto out;
263*2b949d04SAndroid Build Coastguard Worker }
264*2b949d04SAndroid Build Coastguard Worker
265*2b949d04SAndroid Build Coastguard Worker while (true) {
266*2b949d04SAndroid Build Coastguard Worker char buf[4096];
267*2b949d04SAndroid Build Coastguard Worker size_t len;
268*2b949d04SAndroid Build Coastguard Worker
269*2b949d04SAndroid Build Coastguard Worker len = fread(buf, 1, sizeof(buf), stdin);
270*2b949d04SAndroid Build Coastguard Worker if (ferror(stdin)) {
271*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Failed to read from stdin\n");
272*2b949d04SAndroid Build Coastguard Worker goto out;
273*2b949d04SAndroid Build Coastguard Worker }
274*2b949d04SAndroid Build Coastguard Worker if (len > 0) {
275*2b949d04SAndroid Build Coastguard Worker size_t wlen = fwrite(buf, 1, len, file);
276*2b949d04SAndroid Build Coastguard Worker if (wlen != len) {
277*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Failed to write to tmpfile\n");
278*2b949d04SAndroid Build Coastguard Worker goto out;
279*2b949d04SAndroid Build Coastguard Worker }
280*2b949d04SAndroid Build Coastguard Worker }
281*2b949d04SAndroid Build Coastguard Worker if (feof(stdin))
282*2b949d04SAndroid Build Coastguard Worker break;
283*2b949d04SAndroid Build Coastguard Worker }
284*2b949d04SAndroid Build Coastguard Worker fseek(file, 0, SEEK_SET);
285*2b949d04SAndroid Build Coastguard Worker keymap = xkb_keymap_new_from_file(ctx, file,
286*2b949d04SAndroid Build Coastguard Worker XKB_KEYMAP_FORMAT_TEXT_V1, 0);
287*2b949d04SAndroid Build Coastguard Worker if (!keymap) {
288*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Couldn't create xkb keymap\n");
289*2b949d04SAndroid Build Coastguard Worker goto out;
290*2b949d04SAndroid Build Coastguard Worker }
291*2b949d04SAndroid Build Coastguard Worker
292*2b949d04SAndroid Build Coastguard Worker keymap_string = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
293*2b949d04SAndroid Build Coastguard Worker if (!keymap_string) {
294*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Couldn't get the keymap string\n");
295*2b949d04SAndroid Build Coastguard Worker goto out;
296*2b949d04SAndroid Build Coastguard Worker }
297*2b949d04SAndroid Build Coastguard Worker
298*2b949d04SAndroid Build Coastguard Worker fputs(keymap_string, stdout);
299*2b949d04SAndroid Build Coastguard Worker success = true;
300*2b949d04SAndroid Build Coastguard Worker
301*2b949d04SAndroid Build Coastguard Worker out:
302*2b949d04SAndroid Build Coastguard Worker if (file)
303*2b949d04SAndroid Build Coastguard Worker fclose(file);
304*2b949d04SAndroid Build Coastguard Worker xkb_keymap_unref(keymap);
305*2b949d04SAndroid Build Coastguard Worker free(keymap_string);
306*2b949d04SAndroid Build Coastguard Worker
307*2b949d04SAndroid Build Coastguard Worker return success;
308*2b949d04SAndroid Build Coastguard Worker }
309*2b949d04SAndroid Build Coastguard Worker
310*2b949d04SAndroid Build Coastguard Worker int
main(int argc,char ** argv)311*2b949d04SAndroid Build Coastguard Worker main(int argc, char **argv)
312*2b949d04SAndroid Build Coastguard Worker {
313*2b949d04SAndroid Build Coastguard Worker struct xkb_context *ctx;
314*2b949d04SAndroid Build Coastguard Worker struct xkb_rule_names names = {
315*2b949d04SAndroid Build Coastguard Worker .rules = DEFAULT_XKB_RULES,
316*2b949d04SAndroid Build Coastguard Worker .model = DEFAULT_XKB_MODEL,
317*2b949d04SAndroid Build Coastguard Worker /* layout and variant are tied together, so we either get user-supplied for
318*2b949d04SAndroid Build Coastguard Worker * both or default for both, see below */
319*2b949d04SAndroid Build Coastguard Worker .layout = NULL,
320*2b949d04SAndroid Build Coastguard Worker .variant = NULL,
321*2b949d04SAndroid Build Coastguard Worker .options = DEFAULT_XKB_OPTIONS,
322*2b949d04SAndroid Build Coastguard Worker };
323*2b949d04SAndroid Build Coastguard Worker int rc = 1;
324*2b949d04SAndroid Build Coastguard Worker
325*2b949d04SAndroid Build Coastguard Worker if (argc <= 1) {
326*2b949d04SAndroid Build Coastguard Worker usage(argv);
327*2b949d04SAndroid Build Coastguard Worker return EXIT_INVALID_USAGE;
328*2b949d04SAndroid Build Coastguard Worker }
329*2b949d04SAndroid Build Coastguard Worker
330*2b949d04SAndroid Build Coastguard Worker if (!parse_options(argc, argv, &names))
331*2b949d04SAndroid Build Coastguard Worker return EXIT_INVALID_USAGE;
332*2b949d04SAndroid Build Coastguard Worker
333*2b949d04SAndroid Build Coastguard Worker /* Now fill in the layout */
334*2b949d04SAndroid Build Coastguard Worker if (!names.layout || !*names.layout) {
335*2b949d04SAndroid Build Coastguard Worker if (names.variant && *names.variant) {
336*2b949d04SAndroid Build Coastguard Worker fprintf(stderr, "Error: a variant requires a layout\n");
337*2b949d04SAndroid Build Coastguard Worker return EXIT_INVALID_USAGE;
338*2b949d04SAndroid Build Coastguard Worker }
339*2b949d04SAndroid Build Coastguard Worker names.layout = DEFAULT_XKB_LAYOUT;
340*2b949d04SAndroid Build Coastguard Worker names.variant = DEFAULT_XKB_VARIANT;
341*2b949d04SAndroid Build Coastguard Worker }
342*2b949d04SAndroid Build Coastguard Worker
343*2b949d04SAndroid Build Coastguard Worker ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
344*2b949d04SAndroid Build Coastguard Worker assert(ctx);
345*2b949d04SAndroid Build Coastguard Worker
346*2b949d04SAndroid Build Coastguard Worker if (verbose) {
347*2b949d04SAndroid Build Coastguard Worker xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_DEBUG);
348*2b949d04SAndroid Build Coastguard Worker xkb_context_set_log_verbosity(ctx, 10);
349*2b949d04SAndroid Build Coastguard Worker }
350*2b949d04SAndroid Build Coastguard Worker
351*2b949d04SAndroid Build Coastguard Worker if (num_includes == 0)
352*2b949d04SAndroid Build Coastguard Worker includes[num_includes++] = DEFAULT_INCLUDE_PATH_PLACEHOLDER;
353*2b949d04SAndroid Build Coastguard Worker
354*2b949d04SAndroid Build Coastguard Worker for (size_t i = 0; i < num_includes; i++) {
355*2b949d04SAndroid Build Coastguard Worker const char *include = includes[i];
356*2b949d04SAndroid Build Coastguard Worker if (strcmp(include, DEFAULT_INCLUDE_PATH_PLACEHOLDER) == 0)
357*2b949d04SAndroid Build Coastguard Worker xkb_context_include_path_append_default(ctx);
358*2b949d04SAndroid Build Coastguard Worker else
359*2b949d04SAndroid Build Coastguard Worker xkb_context_include_path_append(ctx, include);
360*2b949d04SAndroid Build Coastguard Worker }
361*2b949d04SAndroid Build Coastguard Worker
362*2b949d04SAndroid Build Coastguard Worker if (output_format == FORMAT_RMLVO) {
363*2b949d04SAndroid Build Coastguard Worker rc = print_rmlvo(ctx, &names) ? EXIT_SUCCESS : EXIT_FAILURE;
364*2b949d04SAndroid Build Coastguard Worker } else if (output_format == FORMAT_KEYMAP) {
365*2b949d04SAndroid Build Coastguard Worker rc = print_keymap(ctx, &names) ? EXIT_SUCCESS : EXIT_FAILURE;
366*2b949d04SAndroid Build Coastguard Worker } else if (output_format == FORMAT_KCCGST) {
367*2b949d04SAndroid Build Coastguard Worker rc = print_kccgst(ctx, &names) ? EXIT_SUCCESS : EXIT_FAILURE;
368*2b949d04SAndroid Build Coastguard Worker } else if (output_format == FORMAT_KEYMAP_FROM_XKB) {
369*2b949d04SAndroid Build Coastguard Worker rc = print_keymap_from_file(ctx);
370*2b949d04SAndroid Build Coastguard Worker }
371*2b949d04SAndroid Build Coastguard Worker
372*2b949d04SAndroid Build Coastguard Worker xkb_context_unref(ctx);
373*2b949d04SAndroid Build Coastguard Worker
374*2b949d04SAndroid Build Coastguard Worker return rc;
375*2b949d04SAndroid Build Coastguard Worker }
376