xkbprint.c revision 2f167a42
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 59static unsigned outputFormat = WANT_DEFAULT; 60static const char * wantLocale = "C"; 61static char * rootDir; 62static char * inputFile; 63static char * outputFile; 64static char * outputFont = NULL; 65static char * inDpyName; 66static char * outDpyName; 67static Display * inDpy; 68static Display * outDpy; 69static XKBPrintArgs args; 70static unsigned warningLevel = 5; 71static Bool synch; 72 73/***====================================================================***/ 74 75static void 76Usage(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 127static Bool 128parseArgs(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 574static Display * 575GetDisplay(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 615int 616main(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