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