1 /************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
3
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.
15
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.
24
25 ********************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <X11/Xlocale.h>
34 #include <X11/X.h>
35 #include <X11/Xlib.h>
36 #include <X11/XKBlib.h>
37 #include <X11/extensions/XKBgeom.h>
38 #include <X11/extensions/XKM.h>
39 #include <X11/extensions/XKBfile.h>
40 #include <X11/keysym.h>
41
42 #if defined(sgi)
43 #include <malloc.h>
44 #endif
45
46 #include <stdlib.h>
47
48 #include "utils.h"
49 #include "xkbprint.h"
50
51 /***====================================================================***/
52
53
54 #define WANT_DEFAULT 0
55 #define WANT_PS_FILE 1
56 #define WANT_X_SERVER 2
57
58
59 static unsigned outputFormat = WANT_DEFAULT;
60 static const char * wantLocale = "C";
61 static char * rootDir;
62 static char * inputFile;
63 static char * outputFile;
64 static char * outputFont = NULL;
65 static char * inDpyName;
66 static char * outDpyName;
67 static Display * inDpy;
68 static Display * outDpy;
69 static XKBPrintArgs args;
70 static unsigned warningLevel = 5;
71 static Bool synch;
72
73 /***====================================================================***/
74
75 static void
Usage(int argc,char * argv[])76 Usage(int argc, char *argv[])
77 {
78 fprintf(stderr, "Usage: %s [options] input-file [ output-file ]\n%s",
79 argv[0],
80 "Legal options:\n"
81 "-?,-help Print this message\n"
82 "-color Use colors from geometry\n"
83 #ifdef DEBUG
84 "-d [flags] Report debugging information\n"
85 #endif
86 "-dflts Compute defaults for missing components\n"
87 "-diffs Only show explicit key definitions\n"
88 "-eps Generate an EPS file\n"
89 "-fit Fit keyboard image on page (default)\n"
90 "-full Print keyboard image full sized\n"
91 "-grid <n> Print a grid with <n> mm resolution\n"
92 "-if <name> Specifies the name of an internal font to dump\n"
93 #ifdef DEBUG
94 "-I[<dir>] Specifies a top level directory\n"
95 " for include directives. You can\n"
96 " specify multiple directories.\n"
97 #endif
98 "-kc Also print keycodes, if possible\n"
99 "-label <what> Specifies the label to be drawn on keys\n"
100 " Legal values for <what> are:\n"
101 " none,name,code,symbols\n"
102 "-lc <locale> Use <locale> for fonts and symbols\n"
103 "-level1 Use level 1 PostScript (default)\n"
104 "-level2 Use level 2 PostScript\n"
105 "-lg <num> Use keyboard group <num> to print labels\n"
106 "-ll <num> Use shift level <num> to print labels\n"
107 "-mono Ignore colors from geometry (default)\n"
108 "-n <num> Print <num> copies (default 1)\n"
109 "-nkg <num> Number of groups to print on each key\n"
110 "-nokc Don't print keycodes, even if possible\n"
111 "-npk <num> Number of keyboards to print on each page\n"
112 "-ntg <num> Total number of groups to print\n"
113 "-o <file> Specifies output file name\n"
114 "-R[<DIR>] Specifies the root directory for relative\n"
115 " path names\n"
116 "-pict <what> Specifies use of pictographs instead of\n"
117 " keysym names where available, <what> can\n"
118 " be \"all\", \"none\" or \"common\" (default)\n"
119 "-synch Force synchronization\n"
120 "-version Print program version\n"
121 "-w <lvl> Set warning level (0=none, 10=all)\n"
122 );
123 }
124
125 /***====================================================================***/
126
127 static Bool
parseArgs(int argc,char * argv[])128 parseArgs(int argc, char *argv[])
129 {
130 register int i;
131
132 args.copies = 1;
133 args.grid = 0;
134 args.level1 = True;
135 args.scaleToFit = True;
136 args.wantColor = False;
137 args.wantSymbols = COMMON_SYMBOLS;
138 args.wantKeycodes = True;
139 args.wantDiffs = False;
140 args.wantEPS = False;
141 args.label = LABEL_AUTO;
142 args.baseLabelGroup = 0;
143 args.nLabelGroups = 1;
144 args.nTotalGroups = 0;
145 args.nKBPerPage = 0;
146 args.labelLevel = 0;
147 for (i = 1; i < argc; i++) {
148 if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-"))) {
149 if (inputFile == NULL) {
150 inputFile = argv[i];
151 }
152 else if (outputFile == NULL) {
153 outputFile = argv[i];
154 }
155 else {
156 uWarning("Too many file names on command line\n");
157 uAction("Compiling %s, writing to %s, ignoring %s\n",
158 inputFile, outputFile, argv[i]);
159 }
160 }
161 else if ((strcmp(argv[i], "-?") == 0) ||
162 (strcmp(argv[i], "-help") == 0)) {
163 Usage(argc, argv);
164 exit(0);
165 }
166 else if (strcmp(argv[i], "-color") == 0) {
167 args.wantColor = True;
168 }
169 #ifdef DEBUG
170 else if (strcmp(argv[i], "-d") == 0) {
171 if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) {
172 debugFlags = 1;
173 }
174 else {
175 sscanf(argv[++i], "%i", &debugFlags);
176 }
177 uInformation("Setting debug flags to %d\n", debugFlags);
178 }
179 #endif
180 else if (strcmp(argv[i], "-dflts") == 0) {
181 uWarning("Compute defaults not implemented yet\n");
182 }
183 else if (strcmp(argv[i], "-diffs") == 0) {
184 args.wantDiffs = True;
185 }
186 else if (strcmp(argv[i], "-eps") == 0) {
187 args.wantEPS = True;
188 }
189 else if (strcmp(argv[i], "-fit") == 0) {
190 args.scaleToFit = True;
191 }
192 else if (strcmp(argv[i], "-full") == 0) {
193 args.scaleToFit = False;
194 }
195 else if (strcmp(argv[i], "-grid") == 0) {
196 int tmp;
197
198 if (++i >= argc) {
199 uWarning("Grid frequency not specified\n");
200 uAction("Trailing \"-grid\" option ignored\n");
201 }
202 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) {
203 uWarning("Grid frequency must be an integer > zero\n");
204 uAction("Illegal frequency %d ignored\n", tmp);
205 }
206 else
207 args.grid = tmp;
208 }
209 else if (strcmp(argv[i], "-if") == 0) {
210 if (++i >= argc) {
211 uWarning("Internal Font name not specified\n");
212 uAction("Trailing \"-if\" option ignored\n");
213 }
214 else
215 outputFont = argv[i];
216 }
217 else if (strcmp(argv[i], "-kc") == 0) {
218 args.wantKeycodes = True;
219 }
220 else if (strcmp(argv[i], "-label") == 0) {
221 if (++i >= argc) {
222 uWarning("Label type not specified\n");
223 uAction("Trailing \"-label\" option ignored\n");
224 }
225 else if (uStrCaseEqual(argv[i], "none"))
226 args.label = LABEL_NONE;
227 else if (uStrCaseEqual(argv[i], "name"))
228 args.label = LABEL_KEYNAME;
229 else if (uStrCaseEqual(argv[i], "code"))
230 args.label = LABEL_KEYCODE;
231 else if (uStrCaseEqual(argv[i], "symbols"))
232 args.label = LABEL_SYMBOLS;
233 else {
234 uWarning("Unknown label type \"%s\" specified\n", argv[i]);
235 uAction("Ignored\n");
236 }
237 }
238 else if (strcmp(argv[i], "-lc") == 0) {
239 if (++i >= argc) {
240 uWarning("Locale not specified\n");
241 uAction("Trailing \"-lc\" option ignored\n");
242 }
243 else
244 wantLocale = argv[i];
245 }
246 else if (strcmp(argv[i], "-lg") == 0) {
247 int tmp;
248
249 if (++i >= argc) {
250 uWarning("Label group not specified\n");
251 uAction("Trailing \"-lg\" option ignored\n");
252 }
253 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) ||
254 (tmp > 4)) {
255 uWarning("Label group must be an integer in the range 1..4\n");
256 uAction("Illegal group %d ignored\n", tmp);
257 }
258 else
259 args.baseLabelGroup = tmp - 1;
260 }
261 else if (strcmp(argv[i], "-ll") == 0) {
262 int tmp;
263
264 if (++i >= argc) {
265 uWarning("Label level not specified\n");
266 uAction("Trailing \"-ll\" option ignored\n");
267 }
268 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) ||
269 (tmp > 255)) {
270 uWarning("Label level must be in the range 1..255\n");
271 uAction("Illegal level %d ignored\n", tmp);
272 }
273 else
274 args.labelLevel = tmp - 1;
275 }
276 else if (strcmp(argv[i], "-level1") == 0)
277 args.level1 = True;
278 else if (strcmp(argv[i], "-level2") == 0)
279 args.level1 = False;
280 else if (strcmp(argv[i], "-mono") == 0) {
281 args.wantColor = False;
282 }
283 else if (strcmp(argv[i], "-n") == 0) {
284 int tmp;
285
286 if (++i >= argc) {
287 uWarning("Number of copies not specified\n");
288 uAction("Trailing \"-n\" option ignored\n");
289 }
290 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) {
291 uWarning("Number of copies must be an integer > zero\n");
292 uAction("Illegal count %d ignored\n", tmp);
293 }
294 else
295 args.copies = tmp;
296 }
297 else if (strcmp(argv[i], "-nokc") == 0) {
298 args.wantKeycodes = False;
299 }
300 else if (strcmp(argv[i], "-nkg") == 0) {
301 int tmp;
302
303 if (++i >= argc) {
304 uWarning("Number of groups per key not specified\n");
305 uAction("Trailing \"-nkg\" option ignored\n");
306 }
307 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) ||
308 (tmp > 2)) {
309 uWarning("Groups per key must be in the range 1..2\n");
310 uAction("Illegal number of groups %d ignored\n", tmp);
311 }
312 else
313 args.nLabelGroups = tmp;
314 }
315 else if (strcmp(argv[i], "-npk") == 0) {
316 int tmp;
317
318 if (++i >= argc) {
319 uWarning("Number of keyboards per page not specified\n");
320 uAction("Trailing \"-npk\" option ignored\n");
321 }
322 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) ||
323 (tmp > 2)) {
324 uWarning("Keyboards per page must be in the range 1..2\n");
325 uAction("Illegal number of keyboards %d ignored\n", tmp);
326 }
327 else
328 args.nKBPerPage = tmp;
329 }
330 else if (strcmp(argv[i], "-ntg") == 0) {
331 int tmp;
332
333 if (++i >= argc) {
334 uWarning("Total number of groups not specified\n");
335 uAction("Trailing \"-ntg\" option ignored\n");
336 }
337 else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) ||
338 (tmp > 4)) {
339 uWarning("Total number of groups must be in the range 1..4\n");
340 uAction("Illegal number of groups %d ignored\n", tmp);
341 }
342 else
343 args.nTotalGroups = tmp;
344 }
345 else if (strcmp(argv[i], "-o") == 0) {
346 if (++i >= argc) {
347 uWarning("No output file specified\n");
348 uAction("Trailing \"-o\" option ignored\n");
349 }
350 else if (outputFile != NULL) {
351 uWarning("Multiple output files specified\n");
352 uAction("Compiling %s, ignoring %s\n", outputFile, argv[i]);
353 }
354 else
355 outputFile = argv[i];
356 }
357 else if (strncmp(argv[i], "-R", 2) == 0) {
358 if (argv[i][2] == '\0') {
359 uWarning("No root directory specified\n");
360 uAction("Ignoring -R option\n");
361 }
362 else if (rootDir != NULL) {
363 uWarning("Multiple root directories specified\n");
364 uAction("Using %s, ignoring %s\n", rootDir, argv[i]);
365 }
366 else
367 rootDir = &argv[i][2];
368 }
369 else if (strcmp(argv[i], "-pict") == 0) {
370 if (++i >= argc) {
371 uWarning("No level of pictographs specified\n");
372 uAction("Trailing \"-pict\" option ignored\n");
373 }
374 else if (strcmp(argv[i], "none") == 0)
375 args.wantSymbols = NO_SYMBOLS;
376 else if (strcmp(argv[i], "common") == 0)
377 args.wantSymbols = COMMON_SYMBOLS;
378 else if (strcmp(argv[i], "all") == 0)
379 args.wantSymbols = ALL_SYMBOLS;
380 else if (outputFile != NULL) {
381 uWarning("Unknown pictograph level specified\n");
382 uAction("Ignoring illegal value %s\n", argv[i]);
383 }
384 }
385 else if ((strcmp(argv[i], "-synch") == 0) ||
386 (strcmp(argv[i], "-s") == 0)) {
387 synch = True;
388 }
389 else if (strcmp(argv[i], "-version") == 0) {
390 puts(PACKAGE_STRING);
391 exit(0);
392 }
393 else if (strcmp(argv[i], "-w") == 0) {
394 if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) {
395 warningLevel = 0;
396 }
397 else {
398 int itmp;
399
400 if (sscanf(argv[++i], "%i", &itmp))
401 warningLevel = itmp;
402 }
403 }
404 else {
405 uError("Unknown flag \"%s\" on command line\n", argv[i]);
406 Usage(argc, argv);
407 return False;
408 }
409 }
410 if (rootDir) {
411 if (warningLevel > 8) {
412 uWarning("Changing root directory to \"%s\"\n", rootDir);
413 }
414 if ((chdir(rootDir) < 0) && (warningLevel > 0)) {
415 uWarning("Couldn't change root directory to \"%s\"\n", rootDir);
416 uAction("Root directory (-R) option ignored\n");
417 }
418 }
419 if (outputFont != NULL) {
420 Bool ok;
421 FILE *file = NULL;
422
423 if (outputFile == NULL) {
424 asprintf(&outputFile, "%s.pfa", outputFont);
425 }
426 else if (uStringEqual(outputFile, "-"))
427 file = stdout;
428
429 if (file == NULL)
430 file = fopen(outputFile, "w");
431
432 if (!file) {
433 uError("Couldn't open \"%s\" to dump internal font \"%s\"\n",
434 outputFile, outputFont);
435 uAction("Exiting\n");
436 exit(1);
437 }
438 ok = DumpInternalFont(file, outputFont);
439 if (file != stdout)
440 fclose(file);
441 if (!ok) {
442 uWarning("No internal font to dump\n");
443 if (file != stdout) {
444 uAction("Removing \"%s\"\n", outputFile);
445 unlink(outputFile);
446 }
447 }
448 exit((ok != 0));
449 }
450 if (inputFile == NULL) {
451 uError("No input file specified\n");
452 Usage(argc, argv);
453 return False;
454 }
455 else if (uStringEqual(inputFile, "-")) {
456 /* Nothing */
457 }
458 else if (strchr(inputFile, ':') == NULL) {
459 size_t len = strlen(inputFile);
460
461 if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) {
462 /* Nothing */
463 }
464 else {
465 FILE *file;
466
467 file = fopen(inputFile, "r");
468 if (file) {
469 fclose(file);
470 }
471 else {
472 fprintf(stderr, "Cannot open \"%s\" for reading\n", inputFile);
473 return False;
474 }
475 }
476 }
477 else {
478 inDpyName = inputFile;
479 inputFile = NULL;
480 }
481
482 if (outputFormat == WANT_DEFAULT)
483 outputFormat = WANT_PS_FILE;
484 if ((outputFile == NULL) && (inputFile != NULL) &&
485 uStringEqual(inputFile, "-")) {
486 size_t len;
487
488 len = strlen("stdin.eps") + 2;
489 outputFile = calloc(len, sizeof(char));
490
491 if (outputFile == NULL) {
492 uInternalError("Cannot allocate space for output file name\n");
493 uAction("Exiting\n");
494 exit(1);
495 }
496 if (args.wantEPS)
497 snprintf(outputFile, len, "stdin.eps");
498 else
499 snprintf(outputFile, len, "stdin.ps");
500 }
501 else if ((outputFile == NULL) && (inputFile != NULL)) {
502 size_t len;
503 char *base, *ext;
504
505 base = strrchr(inputFile, '/');
506 if (base == NULL)
507 base = inputFile;
508 else
509 base++;
510
511 len = strlen(base) + strlen("eps") + 2;
512 outputFile = calloc(len, sizeof(char));
513
514 if (outputFile == NULL) {
515 uInternalError("Cannot allocate space for output file name\n");
516 uAction("Exiting\n");
517 exit(1);
518 }
519 ext = strrchr(base, '.');
520 if (ext == NULL) {
521 if (args.wantEPS)
522 snprintf(outputFile, len, "%s.eps", base);
523 else
524 snprintf(outputFile, len, "%s.ps", base);
525 }
526 else {
527 strcpy(outputFile, base);
528 if (args.wantEPS)
529 strcpy(&outputFile[ext - base + 1], "eps");
530 else
531 strcpy(&outputFile[ext - base + 1], "ps");
532 }
533 }
534 else if (outputFile == NULL) {
535 size_t len;
536 char *ch, *name, buf[128];
537
538 if (inDpyName[0] == ':')
539 snprintf(name = buf, sizeof(buf), "server%s", inDpyName);
540 else
541 name = inDpyName;
542
543 len = strlen(name) + strlen("eps") + 2;
544 outputFile = calloc(len, sizeof(char));
545
546 if (outputFile == NULL) {
547 uInternalError("Cannot allocate space for output file name\n");
548 uAction("Exiting\n");
549 exit(1);
550 }
551 strcpy(outputFile, name);
552 for (ch = outputFile; (*ch) != '\0'; ch++) {
553 if (*ch == ':')
554 *ch = '-';
555 else if (*ch == '.')
556 *ch = '_';
557 }
558 *ch++ = '.';
559 if (args.wantEPS)
560 strcpy(ch, "eps");
561 else
562 strcpy(ch, "ps");
563 }
564 else if (strchr(outputFile, ':') != NULL) {
565 outDpyName = outputFile;
566 outputFile = NULL;
567 outputFormat = WANT_X_SERVER;
568 uInternalError("Output to an X server not implemented yet\n");
569 return False;
570 }
571 return True;
572 }
573
574 static Display *
GetDisplay(char * program,char * dpyName)575 GetDisplay(char *program, char *dpyName)
576 {
577 int mjr, mnr, error;
578 Display *dpy;
579
580 mjr = XkbMajorVersion;
581 mnr = XkbMinorVersion;
582 dpy = XkbOpenDisplay(dpyName, NULL, NULL, &mjr, &mnr, &error);
583 if (dpy == NULL) {
584 switch (error) {
585 case XkbOD_BadLibraryVersion:
586 uInformation("%s was compiled with XKB version %d.%02d\n",
587 program, XkbMajorVersion, XkbMinorVersion);
588 uError("X library supports incompatible version %d.%02d\n",
589 mjr, mnr);
590 break;
591 case XkbOD_ConnectionRefused:
592 uError("Cannot open display \"%s\"\n", dpyName);
593 break;
594 case XkbOD_NonXkbServer:
595 uError("XKB extension not present on %s\n", dpyName);
596 break;
597 case XkbOD_BadServerVersion:
598 uInformation("%s was compiled with XKB version %d.%02d\n",
599 program, XkbMajorVersion, XkbMinorVersion);
600 uError("Server %s uses incompatible version %d.%02d\n",
601 dpyName, mjr, mnr);
602 break;
603 default:
604 uInternalError("Unknown error %d from XkbOpenDisplay\n", error);
605 }
606 }
607 else if (synch)
608 XSynchronize(dpy, True);
609 return dpy;
610 }
611
612 /***====================================================================***/
613
614
615 int
main(int argc,char * argv[])616 main(int argc, char *argv[])
617 {
618 FILE *file;
619 int ok;
620 XkbFileInfo result;
621
622 uSetErrorFile(NullString);
623 if (!parseArgs(argc, argv))
624 exit(1);
625 #ifdef DEBUG
626 #ifdef sgi
627 if (debugFlags & 0x4)
628 mallopt(M_DEBUG, 1);
629 #endif
630 #endif
631 file = NULL;
632 XkbInitAtoms(NULL);
633 /* XkbInitIncludePath(); */
634 if (inputFile != NULL) {
635 if (uStringEqual(inputFile, "-")) {
636 static char in[] = "stdin";
637
638 file = stdin;
639 inputFile = in;
640 }
641 else {
642 file = fopen(inputFile, "r");
643 }
644 }
645 else if (inDpyName != NULL) {
646 inDpy = GetDisplay(argv[0], inDpyName);
647 if (!inDpy) {
648 uAction("Exiting\n");
649 exit(1);
650 }
651 }
652 if (outDpyName != NULL) {
653 uInternalError("Output to an X server not implemented yet\n");
654 outDpy = GetDisplay(argv[0], outDpyName);
655 if (!outDpy) {
656 uAction("Exiting\n");
657 exit(1);
658 }
659 }
660 if ((inDpy == NULL) && (outDpy == NULL)) {
661 int mjr, mnr;
662
663 mjr = XkbMajorVersion;
664 mnr = XkbMinorVersion;
665 if (!XkbLibraryVersion(&mjr, &mnr)) {
666 uInformation("%s was compiled with XKB version %d.%02d\n",
667 argv[0], XkbMajorVersion, XkbMinorVersion);
668 uError("X library supports incompatible version %d.%02d\n",
669 mjr, mnr);
670 uAction("Exiting\n");
671 exit(1);
672 }
673 }
674 ok = True;
675 if (file) {
676 unsigned tmp;
677
678 bzero((char *) &result, sizeof(result));
679 if ((result.xkb = XkbAllocKeyboard()) == NULL) {
680 uFatalError("Cannot allocate keyboard description\n");
681 /* NOTREACHED */
682 }
683 tmp = XkmReadFile(file, XkmGeometryMask, XkmKeymapLegal, &result);
684 if ((tmp & XkmGeometryMask) != 0) {
685 uError("Couldn't read geometry from XKM file \"%s\"\n", inputFile);
686 uAction("Exiting\n");
687 ok = False;
688 }
689 if ((tmp & XkmKeyNamesMask) != 0)
690 args.wantKeycodes = False;
691 if (args.label == LABEL_AUTO) {
692 if (result.defined & XkmSymbolsMask)
693 args.label = LABEL_SYMBOLS;
694 else if (result.defined & XkmKeyNamesMask)
695 args.label = LABEL_KEYCODE;
696 else
697 args.label = LABEL_KEYNAME;
698 }
699 else if ((args.label == LABEL_KEYCODE) &&
700 ((tmp & XkmKeyNamesMask) != 0)) {
701 uError("XKM file \"%s\" doesn't have keycodes\n", inputFile);
702 uAction("Cannot label keys as requested. Exiting\n");
703 ok = False;
704 }
705 else if ((args.label == LABEL_SYMBOLS) && ((tmp & XkmSymbolsMask) != 0)) {
706 uError("XKM file \"%s\" doesn't have symbols\n", inputFile);
707 uAction("Cannot label keys as requested. Exiting\n");
708 ok = False;
709 }
710 }
711 else if (inDpy != NULL) {
712 bzero((char *) &result, sizeof(result));
713 result.type = XkmKeymapFile;
714 result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
715 if (result.xkb == NULL)
716 uWarning("Cannot load keyboard description\n");
717 if (XkbGetNames(inDpy, XkbAllNamesMask, result.xkb) != Success)
718 uWarning("Cannot load names\n");
719 if (XkbGetGeometry(inDpy, result.xkb) != Success) {
720 uFatalError("Cannot load geometry for %s\n", inDpyName);
721 }
722 if (args.label == LABEL_AUTO)
723 args.label = LABEL_SYMBOLS;
724 }
725 else {
726 fprintf(stderr, "Cannot open \"%s\" to read geometry\n", inputFile);
727 ok = 0;
728 }
729 if (ok) {
730 FILE *out = NULL;
731
732 if (setlocale(LC_ALL, (wantLocale)) == NULL) {
733 if (wantLocale != NULL) {
734 uWarning("Couldn't change to locale %s\n", wantLocale);
735 uAction("Using \"C\" locale, instead\n");
736 }
737 }
738 /* need C numerics so decimal point doesn't get screwed up */
739 setlocale(LC_NUMERIC, "C");
740 if ((inDpy != outDpy) &&
741 (XkbChangeKbdDisplay(outDpy, &result) != Success)) {
742 uInternalError("Error converting keyboard display from %s to %s\n",
743 inDpyName, outDpyName);
744 exit(1);
745 }
746 if (outputFile != NULL) {
747 if (uStringEqual(outputFile, "-")) {
748 static char of[] = "stdout";
749
750 out = stdout;
751 outputFile = of;
752 }
753 else {
754 out = fopen(outputFile, "w");
755 if (out == NULL) {
756 uError("Cannot open \"%s\" to write keyboard description\n",
757 outputFile);
758 uAction("Exiting\n");
759 exit(1);
760 }
761 }
762 }
763 switch (outputFormat) {
764 case WANT_PS_FILE:
765 ok = GeometryToPostScript(out, &result, &args);
766 break;
767 case WANT_X_SERVER:
768 uInternalError("Output to X server not implemented yet\n");
769 break;
770 default:
771 uInternalError("Unknown output format %d\n", outputFormat);
772 uAction("No output file created\n");
773 ok = False;
774 break;
775 }
776 if (!ok) {
777 uError("Error creating output file\n");
778 }
779 }
780 if (inDpy)
781 XCloseDisplay(inDpy);
782 inDpy = NULL;
783 if (outDpy)
784 XCloseDisplay(outDpy);
785 return (ok == 0);
786 }
787