xkbprint.c revision 2f167a42
10e20ee16Smrg/************************************************************ 20e20ee16Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 30e20ee16Smrg 40e20ee16Smrg Permission to use, copy, modify, and distribute this 50e20ee16Smrg software and its documentation for any purpose and without 60e20ee16Smrg fee is hereby granted, provided that the above copyright 70e20ee16Smrg notice appear in all copies and that both that copyright 80e20ee16Smrg notice and this permission notice appear in supporting 92f167a42Smrg documentation, and that the name of Silicon Graphics not be 102f167a42Smrg used in advertising or publicity pertaining to distribution 110e20ee16Smrg of the software without specific prior written permission. 122f167a42Smrg Silicon Graphics makes no representation about the suitability 130e20ee16Smrg of this software for any purpose. It is provided "as is" 140e20ee16Smrg without any express or implied warranty. 152f167a42Smrg 162f167a42Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 172f167a42Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 180e20ee16Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 192f167a42Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 202f167a42Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 212f167a42Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 220e20ee16Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 230e20ee16Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 240e20ee16Smrg 250e20ee16Smrg ********************************************************/ 262f167a42Smrg 272f167a42Smrg#ifdef HAVE_CONFIG_H 282f167a42Smrg#include "config.h" 292f167a42Smrg#endif 300e20ee16Smrg 310e20ee16Smrg#include <stdio.h> 320e20ee16Smrg#include <ctype.h> 330e20ee16Smrg#include <X11/Xlocale.h> 340e20ee16Smrg#include <X11/X.h> 350e20ee16Smrg#include <X11/Xlib.h> 360e20ee16Smrg#include <X11/XKBlib.h> 370e20ee16Smrg#include <X11/extensions/XKBgeom.h> 380e20ee16Smrg#include <X11/extensions/XKM.h> 390e20ee16Smrg#include <X11/extensions/XKBfile.h> 400e20ee16Smrg#include <X11/keysym.h> 410e20ee16Smrg 420e20ee16Smrg#if defined(sgi) 430e20ee16Smrg#include <malloc.h> 440e20ee16Smrg#endif 450e20ee16Smrg 460e20ee16Smrg#include <stdlib.h> 470e20ee16Smrg 480e20ee16Smrg#include "utils.h" 490e20ee16Smrg#include "xkbprint.h" 500e20ee16Smrg 510e20ee16Smrg/***====================================================================***/ 520e20ee16Smrg 530e20ee16Smrg 540e20ee16Smrg#define WANT_DEFAULT 0 550e20ee16Smrg#define WANT_PS_FILE 1 560e20ee16Smrg#define WANT_X_SERVER 2 570e20ee16Smrg 580e20ee16Smrg 592f167a42Smrgstatic unsigned outputFormat = WANT_DEFAULT; 602f167a42Smrgstatic const char * wantLocale = "C"; 612f167a42Smrgstatic char * rootDir; 622f167a42Smrgstatic char * inputFile; 632f167a42Smrgstatic char * outputFile; 642f167a42Smrgstatic char * outputFont = NULL; 652f167a42Smrgstatic char * inDpyName; 662f167a42Smrgstatic char * outDpyName; 672f167a42Smrgstatic Display * inDpy; 682f167a42Smrgstatic Display * outDpy; 692f167a42Smrgstatic XKBPrintArgs args; 702f167a42Smrgstatic unsigned warningLevel = 5; 712f167a42Smrgstatic Bool synch; 720e20ee16Smrg 730e20ee16Smrg/***====================================================================***/ 740e20ee16Smrg 750e20ee16Smrgstatic void 760e20ee16SmrgUsage(int argc, char *argv[]) 770e20ee16Smrg{ 782f167a42Smrg fprintf(stderr, "Usage: %s [options] input-file [ output-file ]\n%s", 792f167a42Smrg argv[0], 802f167a42Smrg "Legal options:\n" 812f167a42Smrg "-?,-help Print this message\n" 822f167a42Smrg "-color Use colors from geometry\n" 830e20ee16Smrg#ifdef DEBUG 842f167a42Smrg "-d [flags] Report debugging information\n" 850e20ee16Smrg#endif 862f167a42Smrg "-dflts Compute defaults for missing components\n" 872f167a42Smrg "-diffs Only show explicit key definitions\n" 882f167a42Smrg "-eps Generate an EPS file\n" 892f167a42Smrg "-fit Fit keyboard image on page (default)\n" 902f167a42Smrg "-full Print keyboard image full sized\n" 912f167a42Smrg "-grid <n> Print a grid with <n> mm resolution\n" 922f167a42Smrg "-if <name> Specifies the name of an internal font to dump\n" 930e20ee16Smrg#ifdef DEBUG 942f167a42Smrg "-I[<dir>] Specifies a top level directory\n" 952f167a42Smrg " for include directives. You can\n" 962f167a42Smrg " specify multiple directories.\n" 970e20ee16Smrg#endif 982f167a42Smrg "-kc Also print keycodes, if possible\n" 992f167a42Smrg "-label <what> Specifies the label to be drawn on keys\n" 1002f167a42Smrg " Legal values for <what> are:\n" 1012f167a42Smrg " none,name,code,symbols\n" 1022f167a42Smrg "-lc <locale> Use <locale> for fonts and symbols\n" 1032f167a42Smrg "-level1 Use level 1 PostScript (default)\n" 1042f167a42Smrg "-level2 Use level 2 PostScript\n" 1052f167a42Smrg "-lg <num> Use keyboard group <num> to print labels\n" 1062f167a42Smrg "-ll <num> Use shift level <num> to print labels\n" 1072f167a42Smrg "-mono Ignore colors from geometry (default)\n" 1082f167a42Smrg "-n <num> Print <num> copies (default 1)\n" 1092f167a42Smrg "-nkg <num> Number of groups to print on each key\n" 1102f167a42Smrg "-nokc Don't print keycodes, even if possible\n" 1112f167a42Smrg "-npk <num> Number of keyboards to print on each page\n" 1122f167a42Smrg "-ntg <num> Total number of groups to print\n" 1132f167a42Smrg "-o <file> Specifies output file name\n" 1142f167a42Smrg "-R[<DIR>] Specifies the root directory for relative\n" 1152f167a42Smrg " path names\n" 1162f167a42Smrg "-pict <what> Specifies use of pictographs instead of\n" 1172f167a42Smrg " keysym names where available, <what> can\n" 1182f167a42Smrg " be \"all\", \"none\" or \"common\" (default)\n" 1192f167a42Smrg "-synch Force synchronization\n" 1202f167a42Smrg "-version Print program version\n" 1212f167a42Smrg "-w <lvl> Set warning level (0=none, 10=all)\n" 1222f167a42Smrg ); 1230e20ee16Smrg} 1240e20ee16Smrg 1250e20ee16Smrg/***====================================================================***/ 1260e20ee16Smrg 1270e20ee16Smrgstatic Bool 1280e20ee16SmrgparseArgs(int argc, char *argv[]) 1290e20ee16Smrg{ 1302f167a42Smrg register int i; 1312f167a42Smrg 1322f167a42Smrg args.copies = 1; 1332f167a42Smrg args.grid = 0; 1342f167a42Smrg args.level1 = True; 1352f167a42Smrg args.scaleToFit = True; 1362f167a42Smrg args.wantColor = False; 1372f167a42Smrg args.wantSymbols = COMMON_SYMBOLS; 1382f167a42Smrg args.wantKeycodes = True; 1392f167a42Smrg args.wantDiffs = False; 1402f167a42Smrg args.wantEPS = False; 1412f167a42Smrg args.label = LABEL_AUTO; 1422f167a42Smrg args.baseLabelGroup = 0; 1432f167a42Smrg args.nLabelGroups = 1; 1442f167a42Smrg args.nTotalGroups = 0; 1452f167a42Smrg args.nKBPerPage = 0; 1462f167a42Smrg args.labelLevel = 0; 1472f167a42Smrg for (i = 1; i < argc; i++) { 1482f167a42Smrg if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-"))) { 1492f167a42Smrg if (inputFile == NULL) { 1502f167a42Smrg inputFile = argv[i]; 1512f167a42Smrg } 1522f167a42Smrg else if (outputFile == NULL) { 1532f167a42Smrg outputFile = argv[i]; 1542f167a42Smrg } 1552f167a42Smrg else { 1562f167a42Smrg uWarning("Too many file names on command line\n"); 1572f167a42Smrg uAction("Compiling %s, writing to %s, ignoring %s\n", 1582f167a42Smrg inputFile, outputFile, argv[i]); 1592f167a42Smrg } 1602f167a42Smrg } 1612f167a42Smrg else if ((strcmp(argv[i], "-?") == 0) || 1622f167a42Smrg (strcmp(argv[i], "-help") == 0)) { 1632f167a42Smrg Usage(argc, argv); 1642f167a42Smrg exit(0); 1652f167a42Smrg } 1662f167a42Smrg else if (strcmp(argv[i], "-color") == 0) { 1672f167a42Smrg args.wantColor = True; 1682f167a42Smrg } 1690e20ee16Smrg#ifdef DEBUG 1702f167a42Smrg else if (strcmp(argv[i], "-d") == 0) { 1712f167a42Smrg if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) { 1722f167a42Smrg debugFlags = 1; 1732f167a42Smrg } 1742f167a42Smrg else { 1752f167a42Smrg sscanf(argv[++i], "%i", &debugFlags); 1762f167a42Smrg } 1772f167a42Smrg uInformation("Setting debug flags to %d\n", debugFlags); 1782f167a42Smrg } 1790e20ee16Smrg#endif 1802f167a42Smrg else if (strcmp(argv[i], "-dflts") == 0) { 1812f167a42Smrg uWarning("Compute defaults not implemented yet\n"); 1822f167a42Smrg } 1832f167a42Smrg else if (strcmp(argv[i], "-diffs") == 0) { 1842f167a42Smrg args.wantDiffs = True; 1852f167a42Smrg } 1862f167a42Smrg else if (strcmp(argv[i], "-eps") == 0) { 1872f167a42Smrg args.wantEPS = True; 1882f167a42Smrg } 1892f167a42Smrg else if (strcmp(argv[i], "-fit") == 0) { 1902f167a42Smrg args.scaleToFit = True; 1912f167a42Smrg } 1922f167a42Smrg else if (strcmp(argv[i], "-full") == 0) { 1932f167a42Smrg args.scaleToFit = False; 1942f167a42Smrg } 1952f167a42Smrg else if (strcmp(argv[i], "-grid") == 0) { 1962f167a42Smrg int tmp; 1972f167a42Smrg 1982f167a42Smrg if (++i >= argc) { 1992f167a42Smrg uWarning("Grid frequency not specified\n"); 2002f167a42Smrg uAction("Trailing \"-grid\" option ignored\n"); 2012f167a42Smrg } 2022f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) { 2032f167a42Smrg uWarning("Grid frequency must be an integer > zero\n"); 2042f167a42Smrg uAction("Illegal frequency %d ignored\n", tmp); 2052f167a42Smrg } 2062f167a42Smrg else 2072f167a42Smrg args.grid = tmp; 2082f167a42Smrg } 2092f167a42Smrg else if (strcmp(argv[i], "-if") == 0) { 2102f167a42Smrg if (++i >= argc) { 2112f167a42Smrg uWarning("Internal Font name not specified\n"); 2122f167a42Smrg uAction("Trailing \"-if\" option ignored\n"); 2132f167a42Smrg } 2142f167a42Smrg else 2152f167a42Smrg outputFont = argv[i]; 2162f167a42Smrg } 2172f167a42Smrg else if (strcmp(argv[i], "-kc") == 0) { 2182f167a42Smrg args.wantKeycodes = True; 2192f167a42Smrg } 2202f167a42Smrg else if (strcmp(argv[i], "-label") == 0) { 2212f167a42Smrg if (++i >= argc) { 2222f167a42Smrg uWarning("Label type not specified\n"); 2232f167a42Smrg uAction("Trailing \"-label\" option ignored\n"); 2242f167a42Smrg } 2252f167a42Smrg else if (uStrCaseEqual(argv[i], "none")) 2262f167a42Smrg args.label = LABEL_NONE; 2272f167a42Smrg else if (uStrCaseEqual(argv[i], "name")) 2282f167a42Smrg args.label = LABEL_KEYNAME; 2292f167a42Smrg else if (uStrCaseEqual(argv[i], "code")) 2302f167a42Smrg args.label = LABEL_KEYCODE; 2312f167a42Smrg else if (uStrCaseEqual(argv[i], "symbols")) 2322f167a42Smrg args.label = LABEL_SYMBOLS; 2332f167a42Smrg else { 2342f167a42Smrg uWarning("Unknown label type \"%s\" specified\n", argv[i]); 2352f167a42Smrg uAction("Ignored\n"); 2362f167a42Smrg } 2372f167a42Smrg } 2382f167a42Smrg else if (strcmp(argv[i], "-lc") == 0) { 2392f167a42Smrg if (++i >= argc) { 2402f167a42Smrg uWarning("Locale not specified\n"); 2412f167a42Smrg uAction("Trailing \"-lc\" option ignored\n"); 2422f167a42Smrg } 2432f167a42Smrg else 2442f167a42Smrg wantLocale = argv[i]; 2452f167a42Smrg } 2462f167a42Smrg else if (strcmp(argv[i], "-lg") == 0) { 2472f167a42Smrg int tmp; 2482f167a42Smrg 2492f167a42Smrg if (++i >= argc) { 2502f167a42Smrg uWarning("Label group not specified\n"); 2512f167a42Smrg uAction("Trailing \"-lg\" option ignored\n"); 2522f167a42Smrg } 2532f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 2542f167a42Smrg (tmp > 4)) { 2552f167a42Smrg uWarning("Label group must be an integer in the range 1..4\n"); 2562f167a42Smrg uAction("Illegal group %d ignored\n", tmp); 2572f167a42Smrg } 2582f167a42Smrg else 2592f167a42Smrg args.baseLabelGroup = tmp - 1; 2602f167a42Smrg } 2612f167a42Smrg else if (strcmp(argv[i], "-ll") == 0) { 2622f167a42Smrg int tmp; 2632f167a42Smrg 2642f167a42Smrg if (++i >= argc) { 2652f167a42Smrg uWarning("Label level not specified\n"); 2662f167a42Smrg uAction("Trailing \"-ll\" option ignored\n"); 2672f167a42Smrg } 2682f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 2692f167a42Smrg (tmp > 255)) { 2702f167a42Smrg uWarning("Label level must be in the range 1..255\n"); 2712f167a42Smrg uAction("Illegal level %d ignored\n", tmp); 2722f167a42Smrg } 2732f167a42Smrg else 2742f167a42Smrg args.labelLevel = tmp - 1; 2752f167a42Smrg } 2762f167a42Smrg else if (strcmp(argv[i], "-level1") == 0) 2772f167a42Smrg args.level1 = True; 2782f167a42Smrg else if (strcmp(argv[i], "-level2") == 0) 2792f167a42Smrg args.level1 = False; 2802f167a42Smrg else if (strcmp(argv[i], "-mono") == 0) { 2812f167a42Smrg args.wantColor = False; 2822f167a42Smrg } 2832f167a42Smrg else if (strcmp(argv[i], "-n") == 0) { 2842f167a42Smrg int tmp; 2852f167a42Smrg 2862f167a42Smrg if (++i >= argc) { 2872f167a42Smrg uWarning("Number of copies not specified\n"); 2882f167a42Smrg uAction("Trailing \"-n\" option ignored\n"); 2892f167a42Smrg } 2902f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) { 2912f167a42Smrg uWarning("Number of copies must be an integer > zero\n"); 2922f167a42Smrg uAction("Illegal count %d ignored\n", tmp); 2932f167a42Smrg } 2942f167a42Smrg else 2952f167a42Smrg args.copies = tmp; 2962f167a42Smrg } 2972f167a42Smrg else if (strcmp(argv[i], "-nokc") == 0) { 2982f167a42Smrg args.wantKeycodes = False; 2992f167a42Smrg } 3002f167a42Smrg else if (strcmp(argv[i], "-nkg") == 0) { 3012f167a42Smrg int tmp; 3022f167a42Smrg 3032f167a42Smrg if (++i >= argc) { 3042f167a42Smrg uWarning("Number of groups per key not specified\n"); 3052f167a42Smrg uAction("Trailing \"-nkg\" option ignored\n"); 3062f167a42Smrg } 3072f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3082f167a42Smrg (tmp > 2)) { 3092f167a42Smrg uWarning("Groups per key must be in the range 1..2\n"); 3102f167a42Smrg uAction("Illegal number of groups %d ignored\n", tmp); 3112f167a42Smrg } 3122f167a42Smrg else 3132f167a42Smrg args.nLabelGroups = tmp; 3142f167a42Smrg } 3152f167a42Smrg else if (strcmp(argv[i], "-npk") == 0) { 3162f167a42Smrg int tmp; 3172f167a42Smrg 3182f167a42Smrg if (++i >= argc) { 3192f167a42Smrg uWarning("Number of keyboards per page not specified\n"); 3202f167a42Smrg uAction("Trailing \"-npk\" option ignored\n"); 3212f167a42Smrg } 3222f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3232f167a42Smrg (tmp > 2)) { 3242f167a42Smrg uWarning("Keyboards per page must be in the range 1..2\n"); 3252f167a42Smrg uAction("Illegal number of keyboards %d ignored\n", tmp); 3262f167a42Smrg } 3272f167a42Smrg else 3282f167a42Smrg args.nKBPerPage = tmp; 3292f167a42Smrg } 3302f167a42Smrg else if (strcmp(argv[i], "-ntg") == 0) { 3312f167a42Smrg int tmp; 3322f167a42Smrg 3332f167a42Smrg if (++i >= argc) { 3342f167a42Smrg uWarning("Total number of groups not specified\n"); 3352f167a42Smrg uAction("Trailing \"-ntg\" option ignored\n"); 3362f167a42Smrg } 3372f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3382f167a42Smrg (tmp > 4)) { 3392f167a42Smrg uWarning("Total number of groups must be in the range 1..4\n"); 3402f167a42Smrg uAction("Illegal number of groups %d ignored\n", tmp); 3412f167a42Smrg } 3422f167a42Smrg else 3432f167a42Smrg args.nTotalGroups = tmp; 3442f167a42Smrg } 3452f167a42Smrg else if (strcmp(argv[i], "-o") == 0) { 3462f167a42Smrg if (++i >= argc) { 3472f167a42Smrg uWarning("No output file specified\n"); 3482f167a42Smrg uAction("Trailing \"-o\" option ignored\n"); 3492f167a42Smrg } 3502f167a42Smrg else if (outputFile != NULL) { 3512f167a42Smrg uWarning("Multiple output files specified\n"); 3522f167a42Smrg uAction("Compiling %s, ignoring %s\n", outputFile, argv[i]); 3532f167a42Smrg } 3542f167a42Smrg else 3552f167a42Smrg outputFile = argv[i]; 3562f167a42Smrg } 3572f167a42Smrg else if (strncmp(argv[i], "-R", 2) == 0) { 3582f167a42Smrg if (argv[i][2] == '\0') { 3592f167a42Smrg uWarning("No root directory specified\n"); 3602f167a42Smrg uAction("Ignoring -R option\n"); 3612f167a42Smrg } 3622f167a42Smrg else if (rootDir != NULL) { 3632f167a42Smrg uWarning("Multiple root directories specified\n"); 3642f167a42Smrg uAction("Using %s, ignoring %s\n", rootDir, argv[i]); 3652f167a42Smrg } 3662f167a42Smrg else 3672f167a42Smrg rootDir = &argv[i][2]; 3682f167a42Smrg } 3692f167a42Smrg else if (strcmp(argv[i], "-pict") == 0) { 3702f167a42Smrg if (++i >= argc) { 3712f167a42Smrg uWarning("No level of pictographs specified\n"); 3722f167a42Smrg uAction("Trailing \"-pict\" option ignored\n"); 3732f167a42Smrg } 3742f167a42Smrg else if (strcmp(argv[i], "none") == 0) 3752f167a42Smrg args.wantSymbols = NO_SYMBOLS; 3762f167a42Smrg else if (strcmp(argv[i], "common") == 0) 3772f167a42Smrg args.wantSymbols = COMMON_SYMBOLS; 3782f167a42Smrg else if (strcmp(argv[i], "all") == 0) 3792f167a42Smrg args.wantSymbols = ALL_SYMBOLS; 3802f167a42Smrg else if (outputFile != NULL) { 3812f167a42Smrg uWarning("Unknown pictograph level specified\n"); 3822f167a42Smrg uAction("Ignoring illegal value %s\n", argv[i]); 3832f167a42Smrg } 3842f167a42Smrg } 3852f167a42Smrg else if ((strcmp(argv[i], "-synch") == 0) || 3862f167a42Smrg (strcmp(argv[i], "-s") == 0)) { 3872f167a42Smrg synch = True; 3882f167a42Smrg } 3892f167a42Smrg else if (strcmp(argv[i], "-version") == 0) { 3902f167a42Smrg puts(PACKAGE_STRING); 3912f167a42Smrg exit(0); 3922f167a42Smrg } 3932f167a42Smrg else if (strcmp(argv[i], "-w") == 0) { 3942f167a42Smrg if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) { 3952f167a42Smrg warningLevel = 0; 3962f167a42Smrg } 3972f167a42Smrg else { 3982f167a42Smrg int itmp; 3992f167a42Smrg 4002f167a42Smrg if (sscanf(argv[++i], "%i", &itmp)) 4012f167a42Smrg warningLevel = itmp; 4022f167a42Smrg } 4032f167a42Smrg } 4042f167a42Smrg else { 4052f167a42Smrg uError("Unknown flag \"%s\" on command line\n", argv[i]); 4062f167a42Smrg Usage(argc, argv); 4072f167a42Smrg return False; 4082f167a42Smrg } 4090e20ee16Smrg } 4100e20ee16Smrg if (rootDir) { 4112f167a42Smrg if (warningLevel > 8) { 4122f167a42Smrg uWarning("Changing root directory to \"%s\"\n", rootDir); 4132f167a42Smrg } 4142f167a42Smrg if ((chdir(rootDir) < 0) && (warningLevel > 0)) { 4152f167a42Smrg uWarning("Couldn't change root directory to \"%s\"\n", rootDir); 4162f167a42Smrg uAction("Root directory (-R) option ignored\n"); 4172f167a42Smrg } 4180e20ee16Smrg } 4192f167a42Smrg if (outputFont != NULL) { 4202f167a42Smrg Bool ok; 4212f167a42Smrg FILE *file = NULL; 4222f167a42Smrg 4232f167a42Smrg if (outputFile == NULL) { 4242f167a42Smrg asprintf(&outputFile, "%s.pfa", outputFont); 4252f167a42Smrg } 4262f167a42Smrg else if (uStringEqual(outputFile, "-")) 4272f167a42Smrg file = stdout; 4282f167a42Smrg 4292f167a42Smrg if (file == NULL) 4302f167a42Smrg file = fopen(outputFile, "w"); 4312f167a42Smrg 4322f167a42Smrg if (!file) { 4332f167a42Smrg uError("Couldn't open \"%s\" to dump internal font \"%s\"\n", 4342f167a42Smrg outputFile, outputFont); 4352f167a42Smrg uAction("Exiting\n"); 4362f167a42Smrg exit(1); 4372f167a42Smrg } 4382f167a42Smrg ok = DumpInternalFont(file, outputFont); 4392f167a42Smrg if (file != stdout) 4402f167a42Smrg fclose(file); 4412f167a42Smrg if (!ok) { 4422f167a42Smrg uWarning("No internal font to dump\n"); 4432f167a42Smrg if (file != stdout) { 4442f167a42Smrg uAction("Removing \"%s\"\n", outputFile); 4452f167a42Smrg unlink(outputFile); 4462f167a42Smrg } 4472f167a42Smrg } 4482f167a42Smrg exit((ok != 0)); 4490e20ee16Smrg } 4502f167a42Smrg if (inputFile == NULL) { 4512f167a42Smrg uError("No input file specified\n"); 4522f167a42Smrg Usage(argc, argv); 4532f167a42Smrg return False; 4540e20ee16Smrg } 4552f167a42Smrg else if (uStringEqual(inputFile, "-")) { 4562f167a42Smrg /* Nothing */ 4570e20ee16Smrg } 4582f167a42Smrg else if (strchr(inputFile, ':') == NULL) { 4592f167a42Smrg size_t len = strlen(inputFile); 4602f167a42Smrg 4612f167a42Smrg if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) { 4622f167a42Smrg /* Nothing */ 4632f167a42Smrg } 4642f167a42Smrg else { 4652f167a42Smrg FILE *file; 4662f167a42Smrg 4672f167a42Smrg file = fopen(inputFile, "r"); 4682f167a42Smrg if (file) { 4692f167a42Smrg fclose(file); 4702f167a42Smrg } 4712f167a42Smrg else { 4722f167a42Smrg fprintf(stderr, "Cannot open \"%s\" for reading\n", inputFile); 4732f167a42Smrg return False; 4742f167a42Smrg } 4752f167a42Smrg } 4760e20ee16Smrg } 4770e20ee16Smrg else { 4782f167a42Smrg inDpyName = inputFile; 4792f167a42Smrg inputFile = NULL; 4800e20ee16Smrg } 4810e20ee16Smrg 4822f167a42Smrg if (outputFormat == WANT_DEFAULT) 4832f167a42Smrg outputFormat = WANT_PS_FILE; 4842f167a42Smrg if ((outputFile == NULL) && (inputFile != NULL) && 4852f167a42Smrg uStringEqual(inputFile, "-")) { 4862f167a42Smrg size_t len; 4872f167a42Smrg 4882f167a42Smrg len = strlen("stdin.eps") + 2; 4892f167a42Smrg outputFile = calloc(len, sizeof(char)); 4902f167a42Smrg 4912f167a42Smrg if (outputFile == NULL) { 4922f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 4932f167a42Smrg uAction("Exiting\n"); 4942f167a42Smrg exit(1); 4952f167a42Smrg } 4962f167a42Smrg if (args.wantEPS) 4972f167a42Smrg snprintf(outputFile, len, "stdin.eps"); 4982f167a42Smrg else 4992f167a42Smrg snprintf(outputFile, len, "stdin.ps"); 5000e20ee16Smrg } 5012f167a42Smrg else if ((outputFile == NULL) && (inputFile != NULL)) { 5022f167a42Smrg size_t len; 5032f167a42Smrg char *base, *ext; 5042f167a42Smrg 5052f167a42Smrg base = strrchr(inputFile, '/'); 5062f167a42Smrg if (base == NULL) 5072f167a42Smrg base = inputFile; 5082f167a42Smrg else 5092f167a42Smrg base++; 5102f167a42Smrg 5112f167a42Smrg len = strlen(base) + strlen("eps") + 2; 5122f167a42Smrg outputFile = calloc(len, sizeof(char)); 5132f167a42Smrg 5142f167a42Smrg if (outputFile == NULL) { 5152f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 5162f167a42Smrg uAction("Exiting\n"); 5172f167a42Smrg exit(1); 5182f167a42Smrg } 5192f167a42Smrg ext = strrchr(base, '.'); 5202f167a42Smrg if (ext == NULL) { 5212f167a42Smrg if (args.wantEPS) 5222f167a42Smrg snprintf(outputFile, len, "%s.eps", base); 5232f167a42Smrg else 5242f167a42Smrg snprintf(outputFile, len, "%s.ps", base); 5252f167a42Smrg } 5262f167a42Smrg else { 5272f167a42Smrg strcpy(outputFile, base); 5282f167a42Smrg if (args.wantEPS) 5292f167a42Smrg strcpy(&outputFile[ext - base + 1], "eps"); 5302f167a42Smrg else 5312f167a42Smrg strcpy(&outputFile[ext - base + 1], "ps"); 5322f167a42Smrg } 5330e20ee16Smrg } 5342f167a42Smrg else if (outputFile == NULL) { 5352f167a42Smrg size_t len; 5362f167a42Smrg char *ch, *name, buf[128]; 5372f167a42Smrg 5382f167a42Smrg if (inDpyName[0] == ':') 5392f167a42Smrg snprintf(name = buf, sizeof(buf), "server%s", inDpyName); 5402f167a42Smrg else 5412f167a42Smrg name = inDpyName; 5422f167a42Smrg 5432f167a42Smrg len = strlen(name) + strlen("eps") + 2; 5442f167a42Smrg outputFile = calloc(len, sizeof(char)); 5452f167a42Smrg 5462f167a42Smrg if (outputFile == NULL) { 5472f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 5482f167a42Smrg uAction("Exiting\n"); 5492f167a42Smrg exit(1); 5502f167a42Smrg } 5512f167a42Smrg strcpy(outputFile, name); 5522f167a42Smrg for (ch = outputFile; (*ch) != '\0'; ch++) { 5532f167a42Smrg if (*ch == ':') 5542f167a42Smrg *ch = '-'; 5552f167a42Smrg else if (*ch == '.') 5562f167a42Smrg *ch = '_'; 5572f167a42Smrg } 5582f167a42Smrg *ch++ = '.'; 5592f167a42Smrg if (args.wantEPS) 5602f167a42Smrg strcpy(ch, "eps"); 5612f167a42Smrg else 5622f167a42Smrg strcpy(ch, "ps"); 5630e20ee16Smrg } 5642f167a42Smrg else if (strchr(outputFile, ':') != NULL) { 5652f167a42Smrg outDpyName = outputFile; 5662f167a42Smrg outputFile = NULL; 5672f167a42Smrg outputFormat = WANT_X_SERVER; 5682f167a42Smrg uInternalError("Output to an X server not implemented yet\n"); 5692f167a42Smrg return False; 5700e20ee16Smrg } 5710e20ee16Smrg return True; 5720e20ee16Smrg} 5730e20ee16Smrg 5740e20ee16Smrgstatic Display * 5750e20ee16SmrgGetDisplay(char *program, char *dpyName) 5760e20ee16Smrg{ 5772f167a42Smrg int mjr, mnr, error; 5782f167a42Smrg Display *dpy; 5792f167a42Smrg 5802f167a42Smrg mjr = XkbMajorVersion; 5812f167a42Smrg mnr = XkbMinorVersion; 5822f167a42Smrg dpy = XkbOpenDisplay(dpyName, NULL, NULL, &mjr, &mnr, &error); 5832f167a42Smrg if (dpy == NULL) { 5842f167a42Smrg switch (error) { 5852f167a42Smrg case XkbOD_BadLibraryVersion: 5862f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 5872f167a42Smrg program, XkbMajorVersion, XkbMinorVersion); 5882f167a42Smrg uError("X library supports incompatible version %d.%02d\n", 5892f167a42Smrg mjr, mnr); 5902f167a42Smrg break; 5912f167a42Smrg case XkbOD_ConnectionRefused: 5922f167a42Smrg uError("Cannot open display \"%s\"\n", dpyName); 5932f167a42Smrg break; 5942f167a42Smrg case XkbOD_NonXkbServer: 5952f167a42Smrg uError("XKB extension not present on %s\n", dpyName); 5962f167a42Smrg break; 5972f167a42Smrg case XkbOD_BadServerVersion: 5982f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 5992f167a42Smrg program, XkbMajorVersion, XkbMinorVersion); 6002f167a42Smrg uError("Server %s uses incompatible version %d.%02d\n", 6012f167a42Smrg dpyName, mjr, mnr); 6022f167a42Smrg break; 6032f167a42Smrg default: 6042f167a42Smrg uInternalError("Unknown error %d from XkbOpenDisplay\n", error); 6052f167a42Smrg } 6060e20ee16Smrg } 6070e20ee16Smrg else if (synch) 6082f167a42Smrg XSynchronize(dpy, True); 6090e20ee16Smrg return dpy; 6100e20ee16Smrg} 6110e20ee16Smrg 6120e20ee16Smrg/***====================================================================***/ 6130e20ee16Smrg 6140e20ee16Smrg 6150e20ee16Smrgint 6160e20ee16Smrgmain(int argc, char *argv[]) 6170e20ee16Smrg{ 6182f167a42Smrg FILE *file; 6192f167a42Smrg int ok; 6202f167a42Smrg XkbFileInfo result; 6210e20ee16Smrg 6220e20ee16Smrg uSetErrorFile(NullString); 6232f167a42Smrg if (!parseArgs(argc, argv)) 6242f167a42Smrg exit(1); 6250e20ee16Smrg#ifdef DEBUG 6260e20ee16Smrg#ifdef sgi 6272f167a42Smrg if (debugFlags & 0x4) 6282f167a42Smrg mallopt(M_DEBUG, 1); 6290e20ee16Smrg#endif 6300e20ee16Smrg#endif 6312f167a42Smrg file = NULL; 6320e20ee16Smrg XkbInitAtoms(NULL); 6330e20ee16Smrg/* XkbInitIncludePath(); */ 6342f167a42Smrg if (inputFile != NULL) { 6352f167a42Smrg if (uStringEqual(inputFile, "-")) { 6362f167a42Smrg static char in[] = "stdin"; 6372f167a42Smrg 6382f167a42Smrg file = stdin; 6392f167a42Smrg inputFile = in; 6402f167a42Smrg } 6412f167a42Smrg else { 6422f167a42Smrg file = fopen(inputFile, "r"); 6432f167a42Smrg } 6440e20ee16Smrg } 6452f167a42Smrg else if (inDpyName != NULL) { 6462f167a42Smrg inDpy = GetDisplay(argv[0], inDpyName); 6472f167a42Smrg if (!inDpy) { 6482f167a42Smrg uAction("Exiting\n"); 6492f167a42Smrg exit(1); 6502f167a42Smrg } 6510e20ee16Smrg } 6522f167a42Smrg if (outDpyName != NULL) { 6532f167a42Smrg uInternalError("Output to an X server not implemented yet\n"); 6542f167a42Smrg outDpy = GetDisplay(argv[0], outDpyName); 6552f167a42Smrg if (!outDpy) { 6562f167a42Smrg uAction("Exiting\n"); 6572f167a42Smrg exit(1); 6582f167a42Smrg } 6590e20ee16Smrg } 6602f167a42Smrg if ((inDpy == NULL) && (outDpy == NULL)) { 6612f167a42Smrg int mjr, mnr; 6622f167a42Smrg 6632f167a42Smrg mjr = XkbMajorVersion; 6642f167a42Smrg mnr = XkbMinorVersion; 6652f167a42Smrg if (!XkbLibraryVersion(&mjr, &mnr)) { 6662f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 6672f167a42Smrg argv[0], XkbMajorVersion, XkbMinorVersion); 6682f167a42Smrg uError("X library supports incompatible version %d.%02d\n", 6692f167a42Smrg mjr, mnr); 6702f167a42Smrg uAction("Exiting\n"); 6712f167a42Smrg exit(1); 6722f167a42Smrg } 6730e20ee16Smrg } 6742f167a42Smrg ok = True; 6750e20ee16Smrg if (file) { 6762f167a42Smrg unsigned tmp; 6772f167a42Smrg 6782f167a42Smrg bzero((char *) &result, sizeof(result)); 6792f167a42Smrg if ((result.xkb = XkbAllocKeyboard()) == NULL) { 6802f167a42Smrg uFatalError("Cannot allocate keyboard description\n"); 6812f167a42Smrg /* NOTREACHED */ 6822f167a42Smrg } 6832f167a42Smrg tmp = XkmReadFile(file, XkmGeometryMask, XkmKeymapLegal, &result); 6842f167a42Smrg if ((tmp & XkmGeometryMask) != 0) { 6852f167a42Smrg uError("Couldn't read geometry from XKM file \"%s\"\n", inputFile); 6862f167a42Smrg uAction("Exiting\n"); 6872f167a42Smrg ok = False; 6882f167a42Smrg } 6892f167a42Smrg if ((tmp & XkmKeyNamesMask) != 0) 6902f167a42Smrg args.wantKeycodes = False; 6912f167a42Smrg if (args.label == LABEL_AUTO) { 6922f167a42Smrg if (result.defined & XkmSymbolsMask) 6932f167a42Smrg args.label = LABEL_SYMBOLS; 6942f167a42Smrg else if (result.defined & XkmKeyNamesMask) 6952f167a42Smrg args.label = LABEL_KEYCODE; 6962f167a42Smrg else 6972f167a42Smrg args.label = LABEL_KEYNAME; 6982f167a42Smrg } 6992f167a42Smrg else if ((args.label == LABEL_KEYCODE) && 7002f167a42Smrg ((tmp & XkmKeyNamesMask) != 0)) { 7012f167a42Smrg uError("XKM file \"%s\" doesn't have keycodes\n", inputFile); 7022f167a42Smrg uAction("Cannot label keys as requested. Exiting\n"); 7032f167a42Smrg ok = False; 7042f167a42Smrg } 7052f167a42Smrg else if ((args.label == LABEL_SYMBOLS) && ((tmp & XkmSymbolsMask) != 0)) { 7062f167a42Smrg uError("XKM file \"%s\" doesn't have symbols\n", inputFile); 7072f167a42Smrg uAction("Cannot label keys as requested. Exiting\n"); 7082f167a42Smrg ok = False; 7092f167a42Smrg } 7100e20ee16Smrg } 7112f167a42Smrg else if (inDpy != NULL) { 7122f167a42Smrg bzero((char *) &result, sizeof(result)); 7132f167a42Smrg result.type = XkmKeymapFile; 7142f167a42Smrg result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask, XkbUseCoreKbd); 7152f167a42Smrg if (result.xkb == NULL) 7162f167a42Smrg uWarning("Cannot load keyboard description\n"); 7172f167a42Smrg if (XkbGetNames(inDpy, XkbAllNamesMask, result.xkb) != Success) 7182f167a42Smrg uWarning("Cannot load names\n"); 7192f167a42Smrg if (XkbGetGeometry(inDpy, result.xkb) != Success) { 7202f167a42Smrg uFatalError("Cannot load geometry for %s\n", inDpyName); 7212f167a42Smrg } 7222f167a42Smrg if (args.label == LABEL_AUTO) 7232f167a42Smrg args.label = LABEL_SYMBOLS; 7240e20ee16Smrg } 7250e20ee16Smrg else { 7262f167a42Smrg fprintf(stderr, "Cannot open \"%s\" to read geometry\n", inputFile); 7272f167a42Smrg ok = 0; 7280e20ee16Smrg } 7290e20ee16Smrg if (ok) { 7302f167a42Smrg FILE *out = NULL; 7312f167a42Smrg 7322f167a42Smrg if (setlocale(LC_ALL, (wantLocale)) == NULL) { 7332f167a42Smrg if (wantLocale != NULL) { 7342f167a42Smrg uWarning("Couldn't change to locale %s\n", wantLocale); 7352f167a42Smrg uAction("Using \"C\" locale, instead\n"); 7362f167a42Smrg } 7372f167a42Smrg } 7382f167a42Smrg /* need C numerics so decimal point doesn't get screwed up */ 7392f167a42Smrg setlocale(LC_NUMERIC, "C"); 7402f167a42Smrg if ((inDpy != outDpy) && 7412f167a42Smrg (XkbChangeKbdDisplay(outDpy, &result) != Success)) { 7422f167a42Smrg uInternalError("Error converting keyboard display from %s to %s\n", 7432f167a42Smrg inDpyName, outDpyName); 7442f167a42Smrg exit(1); 7452f167a42Smrg } 7462f167a42Smrg if (outputFile != NULL) { 7472f167a42Smrg if (uStringEqual(outputFile, "-")) { 7482f167a42Smrg static char of[] = "stdout"; 7492f167a42Smrg 7502f167a42Smrg out = stdout; 7512f167a42Smrg outputFile = of; 7522f167a42Smrg } 7532f167a42Smrg else { 7542f167a42Smrg out = fopen(outputFile, "w"); 7552f167a42Smrg if (out == NULL) { 7562f167a42Smrg uError("Cannot open \"%s\" to write keyboard description\n", 7572f167a42Smrg outputFile); 7582f167a42Smrg uAction("Exiting\n"); 7592f167a42Smrg exit(1); 7602f167a42Smrg } 7612f167a42Smrg } 7622f167a42Smrg } 7632f167a42Smrg switch (outputFormat) { 7642f167a42Smrg case WANT_PS_FILE: 7652f167a42Smrg ok = GeometryToPostScript(out, &result, &args); 7662f167a42Smrg break; 7672f167a42Smrg case WANT_X_SERVER: 7682f167a42Smrg uInternalError("Output to X server not implemented yet\n"); 7692f167a42Smrg break; 7702f167a42Smrg default: 7712f167a42Smrg uInternalError("Unknown output format %d\n", outputFormat); 7722f167a42Smrg uAction("No output file created\n"); 7732f167a42Smrg ok = False; 7742f167a42Smrg break; 7752f167a42Smrg } 7762f167a42Smrg if (!ok) { 7772f167a42Smrg uError("Error creating output file\n"); 7782f167a42Smrg } 7790e20ee16Smrg } 7802f167a42Smrg if (inDpy) 7812f167a42Smrg XCloseDisplay(inDpy); 7822f167a42Smrg inDpy = NULL; 7830e20ee16Smrg if (outDpy) 7842f167a42Smrg XCloseDisplay(outDpy); 7852f167a42Smrg return (ok == 0); 7860e20ee16Smrg} 787