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 430e20ee16Smrg#include <stdlib.h> 440e20ee16Smrg 450e20ee16Smrg#include "utils.h" 460e20ee16Smrg#include "xkbprint.h" 470e20ee16Smrg 480e20ee16Smrg/***====================================================================***/ 490e20ee16Smrg 500e20ee16Smrg 510e20ee16Smrg#define WANT_DEFAULT 0 520e20ee16Smrg#define WANT_PS_FILE 1 530e20ee16Smrg#define WANT_X_SERVER 2 540e20ee16Smrg 550e20ee16Smrg 562f167a42Smrgstatic unsigned outputFormat = WANT_DEFAULT; 572f167a42Smrgstatic const char * wantLocale = "C"; 582f167a42Smrgstatic char * rootDir; 592f167a42Smrgstatic char * inputFile; 602f167a42Smrgstatic char * outputFile; 612f167a42Smrgstatic char * outputFont = NULL; 622f167a42Smrgstatic char * inDpyName; 632f167a42Smrgstatic char * outDpyName; 642f167a42Smrgstatic Display * inDpy; 652f167a42Smrgstatic Display * outDpy; 662f167a42Smrgstatic XKBPrintArgs args; 672f167a42Smrgstatic unsigned warningLevel = 5; 682f167a42Smrgstatic Bool synch; 690e20ee16Smrg 700e20ee16Smrg/***====================================================================***/ 710e20ee16Smrg 720e20ee16Smrgstatic void 730e20ee16SmrgUsage(int argc, char *argv[]) 740e20ee16Smrg{ 752f167a42Smrg fprintf(stderr, "Usage: %s [options] input-file [ output-file ]\n%s", 762f167a42Smrg argv[0], 772f167a42Smrg "Legal options:\n" 782f167a42Smrg "-?,-help Print this message\n" 792f167a42Smrg "-color Use colors from geometry\n" 800e20ee16Smrg#ifdef DEBUG 812f167a42Smrg "-d [flags] Report debugging information\n" 820e20ee16Smrg#endif 832f167a42Smrg "-dflts Compute defaults for missing components\n" 842f167a42Smrg "-diffs Only show explicit key definitions\n" 852f167a42Smrg "-eps Generate an EPS file\n" 862f167a42Smrg "-fit Fit keyboard image on page (default)\n" 872f167a42Smrg "-full Print keyboard image full sized\n" 882f167a42Smrg "-grid <n> Print a grid with <n> mm resolution\n" 892f167a42Smrg "-if <name> Specifies the name of an internal font to dump\n" 900e20ee16Smrg#ifdef DEBUG 912f167a42Smrg "-I[<dir>] Specifies a top level directory\n" 922f167a42Smrg " for include directives. You can\n" 932f167a42Smrg " specify multiple directories.\n" 940e20ee16Smrg#endif 952f167a42Smrg "-kc Also print keycodes, if possible\n" 962f167a42Smrg "-label <what> Specifies the label to be drawn on keys\n" 972f167a42Smrg " Legal values for <what> are:\n" 982f167a42Smrg " none,name,code,symbols\n" 992f167a42Smrg "-lc <locale> Use <locale> for fonts and symbols\n" 1002f167a42Smrg "-level1 Use level 1 PostScript (default)\n" 1012f167a42Smrg "-level2 Use level 2 PostScript\n" 1022f167a42Smrg "-lg <num> Use keyboard group <num> to print labels\n" 1032f167a42Smrg "-ll <num> Use shift level <num> to print labels\n" 1042f167a42Smrg "-mono Ignore colors from geometry (default)\n" 1052f167a42Smrg "-n <num> Print <num> copies (default 1)\n" 1062f167a42Smrg "-nkg <num> Number of groups to print on each key\n" 1072f167a42Smrg "-nokc Don't print keycodes, even if possible\n" 1082f167a42Smrg "-npk <num> Number of keyboards to print on each page\n" 1092f167a42Smrg "-ntg <num> Total number of groups to print\n" 1102f167a42Smrg "-o <file> Specifies output file name\n" 1112f167a42Smrg "-R[<DIR>] Specifies the root directory for relative\n" 1122f167a42Smrg " path names\n" 1132f167a42Smrg "-pict <what> Specifies use of pictographs instead of\n" 1142f167a42Smrg " keysym names where available, <what> can\n" 1152f167a42Smrg " be \"all\", \"none\" or \"common\" (default)\n" 1162f167a42Smrg "-synch Force synchronization\n" 1172f167a42Smrg "-version Print program version\n" 1182f167a42Smrg "-w <lvl> Set warning level (0=none, 10=all)\n" 1192f167a42Smrg ); 1200e20ee16Smrg} 1210e20ee16Smrg 1220e20ee16Smrg/***====================================================================***/ 1230e20ee16Smrg 1240e20ee16Smrgstatic Bool 1250e20ee16SmrgparseArgs(int argc, char *argv[]) 1260e20ee16Smrg{ 1278b648e79Smrg args = (XKBPrintArgs) { 1288b648e79Smrg .copies = 1, 1298b648e79Smrg .grid = 0, 1308b648e79Smrg .level1 = True, 1318b648e79Smrg .scaleToFit = True, 1328b648e79Smrg .wantColor = False, 1338b648e79Smrg .wantSymbols = COMMON_SYMBOLS, 1348b648e79Smrg .wantKeycodes = True, 1358b648e79Smrg .wantDiffs = False, 1368b648e79Smrg .wantEPS = False, 1378b648e79Smrg .label = LABEL_AUTO, 1388b648e79Smrg .baseLabelGroup = 0, 1398b648e79Smrg .nLabelGroups = 1, 1408b648e79Smrg .nTotalGroups = 0, 1418b648e79Smrg .nKBPerPage = 0, 1428b648e79Smrg .labelLevel = 0 1438b648e79Smrg }; 1448b648e79Smrg for (int i = 1; i < argc; i++) { 1452f167a42Smrg if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-"))) { 1462f167a42Smrg if (inputFile == NULL) { 1472f167a42Smrg inputFile = argv[i]; 1482f167a42Smrg } 1492f167a42Smrg else if (outputFile == NULL) { 1502f167a42Smrg outputFile = argv[i]; 1512f167a42Smrg } 1522f167a42Smrg else { 1532f167a42Smrg uWarning("Too many file names on command line\n"); 1542f167a42Smrg uAction("Compiling %s, writing to %s, ignoring %s\n", 1552f167a42Smrg inputFile, outputFile, argv[i]); 1562f167a42Smrg } 1572f167a42Smrg } 1582f167a42Smrg else if ((strcmp(argv[i], "-?") == 0) || 1592f167a42Smrg (strcmp(argv[i], "-help") == 0)) { 1602f167a42Smrg Usage(argc, argv); 1612f167a42Smrg exit(0); 1622f167a42Smrg } 1632f167a42Smrg else if (strcmp(argv[i], "-color") == 0) { 1642f167a42Smrg args.wantColor = True; 1652f167a42Smrg } 1660e20ee16Smrg#ifdef DEBUG 1672f167a42Smrg else if (strcmp(argv[i], "-d") == 0) { 1682f167a42Smrg if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) { 1692f167a42Smrg debugFlags = 1; 1702f167a42Smrg } 1712f167a42Smrg else { 1722f167a42Smrg sscanf(argv[++i], "%i", &debugFlags); 1732f167a42Smrg } 1742f167a42Smrg uInformation("Setting debug flags to %d\n", debugFlags); 1752f167a42Smrg } 1760e20ee16Smrg#endif 1772f167a42Smrg else if (strcmp(argv[i], "-dflts") == 0) { 1782f167a42Smrg uWarning("Compute defaults not implemented yet\n"); 1792f167a42Smrg } 1802f167a42Smrg else if (strcmp(argv[i], "-diffs") == 0) { 1812f167a42Smrg args.wantDiffs = True; 1822f167a42Smrg } 1832f167a42Smrg else if (strcmp(argv[i], "-eps") == 0) { 1842f167a42Smrg args.wantEPS = True; 1852f167a42Smrg } 1862f167a42Smrg else if (strcmp(argv[i], "-fit") == 0) { 1872f167a42Smrg args.scaleToFit = True; 1882f167a42Smrg } 1892f167a42Smrg else if (strcmp(argv[i], "-full") == 0) { 1902f167a42Smrg args.scaleToFit = False; 1912f167a42Smrg } 1922f167a42Smrg else if (strcmp(argv[i], "-grid") == 0) { 1932f167a42Smrg int tmp; 1942f167a42Smrg 1952f167a42Smrg if (++i >= argc) { 1962f167a42Smrg uWarning("Grid frequency not specified\n"); 1972f167a42Smrg uAction("Trailing \"-grid\" option ignored\n"); 1982f167a42Smrg } 1992f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) { 2002f167a42Smrg uWarning("Grid frequency must be an integer > zero\n"); 2012f167a42Smrg uAction("Illegal frequency %d ignored\n", tmp); 2022f167a42Smrg } 2032f167a42Smrg else 2042f167a42Smrg args.grid = tmp; 2052f167a42Smrg } 2062f167a42Smrg else if (strcmp(argv[i], "-if") == 0) { 2072f167a42Smrg if (++i >= argc) { 2082f167a42Smrg uWarning("Internal Font name not specified\n"); 2092f167a42Smrg uAction("Trailing \"-if\" option ignored\n"); 2102f167a42Smrg } 2112f167a42Smrg else 2122f167a42Smrg outputFont = argv[i]; 2132f167a42Smrg } 2142f167a42Smrg else if (strcmp(argv[i], "-kc") == 0) { 2152f167a42Smrg args.wantKeycodes = True; 2162f167a42Smrg } 2172f167a42Smrg else if (strcmp(argv[i], "-label") == 0) { 2182f167a42Smrg if (++i >= argc) { 2192f167a42Smrg uWarning("Label type not specified\n"); 2202f167a42Smrg uAction("Trailing \"-label\" option ignored\n"); 2212f167a42Smrg } 2222f167a42Smrg else if (uStrCaseEqual(argv[i], "none")) 2232f167a42Smrg args.label = LABEL_NONE; 2242f167a42Smrg else if (uStrCaseEqual(argv[i], "name")) 2252f167a42Smrg args.label = LABEL_KEYNAME; 2262f167a42Smrg else if (uStrCaseEqual(argv[i], "code")) 2272f167a42Smrg args.label = LABEL_KEYCODE; 2282f167a42Smrg else if (uStrCaseEqual(argv[i], "symbols")) 2292f167a42Smrg args.label = LABEL_SYMBOLS; 2302f167a42Smrg else { 2312f167a42Smrg uWarning("Unknown label type \"%s\" specified\n", argv[i]); 2322f167a42Smrg uAction("Ignored\n"); 2332f167a42Smrg } 2342f167a42Smrg } 2352f167a42Smrg else if (strcmp(argv[i], "-lc") == 0) { 2362f167a42Smrg if (++i >= argc) { 2372f167a42Smrg uWarning("Locale not specified\n"); 2382f167a42Smrg uAction("Trailing \"-lc\" option ignored\n"); 2392f167a42Smrg } 2402f167a42Smrg else 2412f167a42Smrg wantLocale = argv[i]; 2422f167a42Smrg } 2432f167a42Smrg else if (strcmp(argv[i], "-lg") == 0) { 2442f167a42Smrg int tmp; 2452f167a42Smrg 2462f167a42Smrg if (++i >= argc) { 2472f167a42Smrg uWarning("Label group not specified\n"); 2482f167a42Smrg uAction("Trailing \"-lg\" option ignored\n"); 2492f167a42Smrg } 2502f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 2512f167a42Smrg (tmp > 4)) { 2522f167a42Smrg uWarning("Label group must be an integer in the range 1..4\n"); 2532f167a42Smrg uAction("Illegal group %d ignored\n", tmp); 2542f167a42Smrg } 2552f167a42Smrg else 2562f167a42Smrg args.baseLabelGroup = tmp - 1; 2572f167a42Smrg } 2582f167a42Smrg else if (strcmp(argv[i], "-ll") == 0) { 2592f167a42Smrg int tmp; 2602f167a42Smrg 2612f167a42Smrg if (++i >= argc) { 2622f167a42Smrg uWarning("Label level not specified\n"); 2632f167a42Smrg uAction("Trailing \"-ll\" option ignored\n"); 2642f167a42Smrg } 2652f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 2662f167a42Smrg (tmp > 255)) { 2672f167a42Smrg uWarning("Label level must be in the range 1..255\n"); 2682f167a42Smrg uAction("Illegal level %d ignored\n", tmp); 2692f167a42Smrg } 2702f167a42Smrg else 2712f167a42Smrg args.labelLevel = tmp - 1; 2722f167a42Smrg } 2732f167a42Smrg else if (strcmp(argv[i], "-level1") == 0) 2742f167a42Smrg args.level1 = True; 2752f167a42Smrg else if (strcmp(argv[i], "-level2") == 0) 2762f167a42Smrg args.level1 = False; 2772f167a42Smrg else if (strcmp(argv[i], "-mono") == 0) { 2782f167a42Smrg args.wantColor = False; 2792f167a42Smrg } 2802f167a42Smrg else if (strcmp(argv[i], "-n") == 0) { 2812f167a42Smrg int tmp; 2822f167a42Smrg 2832f167a42Smrg if (++i >= argc) { 2842f167a42Smrg uWarning("Number of copies not specified\n"); 2852f167a42Smrg uAction("Trailing \"-n\" option ignored\n"); 2862f167a42Smrg } 2872f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1)) { 2882f167a42Smrg uWarning("Number of copies must be an integer > zero\n"); 2892f167a42Smrg uAction("Illegal count %d ignored\n", tmp); 2902f167a42Smrg } 2912f167a42Smrg else 2922f167a42Smrg args.copies = tmp; 2932f167a42Smrg } 2942f167a42Smrg else if (strcmp(argv[i], "-nokc") == 0) { 2952f167a42Smrg args.wantKeycodes = False; 2962f167a42Smrg } 2972f167a42Smrg else if (strcmp(argv[i], "-nkg") == 0) { 2982f167a42Smrg int tmp; 2992f167a42Smrg 3002f167a42Smrg if (++i >= argc) { 3012f167a42Smrg uWarning("Number of groups per key not specified\n"); 3022f167a42Smrg uAction("Trailing \"-nkg\" option ignored\n"); 3032f167a42Smrg } 3042f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3052f167a42Smrg (tmp > 2)) { 3062f167a42Smrg uWarning("Groups per key must be in the range 1..2\n"); 3072f167a42Smrg uAction("Illegal number of groups %d ignored\n", tmp); 3082f167a42Smrg } 3092f167a42Smrg else 3102f167a42Smrg args.nLabelGroups = tmp; 3112f167a42Smrg } 3122f167a42Smrg else if (strcmp(argv[i], "-npk") == 0) { 3132f167a42Smrg int tmp; 3142f167a42Smrg 3152f167a42Smrg if (++i >= argc) { 3162f167a42Smrg uWarning("Number of keyboards per page not specified\n"); 3172f167a42Smrg uAction("Trailing \"-npk\" option ignored\n"); 3182f167a42Smrg } 3192f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3202f167a42Smrg (tmp > 2)) { 3212f167a42Smrg uWarning("Keyboards per page must be in the range 1..2\n"); 3222f167a42Smrg uAction("Illegal number of keyboards %d ignored\n", tmp); 3232f167a42Smrg } 3242f167a42Smrg else 3252f167a42Smrg args.nKBPerPage = tmp; 3262f167a42Smrg } 3272f167a42Smrg else if (strcmp(argv[i], "-ntg") == 0) { 3282f167a42Smrg int tmp; 3292f167a42Smrg 3302f167a42Smrg if (++i >= argc) { 3312f167a42Smrg uWarning("Total number of groups not specified\n"); 3322f167a42Smrg uAction("Trailing \"-ntg\" option ignored\n"); 3332f167a42Smrg } 3342f167a42Smrg else if ((sscanf(argv[i], "%i", &tmp) != 1) || (tmp < 1) || 3352f167a42Smrg (tmp > 4)) { 3362f167a42Smrg uWarning("Total number of groups must be in the range 1..4\n"); 3372f167a42Smrg uAction("Illegal number of groups %d ignored\n", tmp); 3382f167a42Smrg } 3392f167a42Smrg else 3402f167a42Smrg args.nTotalGroups = tmp; 3412f167a42Smrg } 3422f167a42Smrg else if (strcmp(argv[i], "-o") == 0) { 3432f167a42Smrg if (++i >= argc) { 3442f167a42Smrg uWarning("No output file specified\n"); 3452f167a42Smrg uAction("Trailing \"-o\" option ignored\n"); 3462f167a42Smrg } 3472f167a42Smrg else if (outputFile != NULL) { 3482f167a42Smrg uWarning("Multiple output files specified\n"); 3492f167a42Smrg uAction("Compiling %s, ignoring %s\n", outputFile, argv[i]); 3502f167a42Smrg } 3512f167a42Smrg else 3522f167a42Smrg outputFile = argv[i]; 3532f167a42Smrg } 3542f167a42Smrg else if (strncmp(argv[i], "-R", 2) == 0) { 3552f167a42Smrg if (argv[i][2] == '\0') { 3562f167a42Smrg uWarning("No root directory specified\n"); 3572f167a42Smrg uAction("Ignoring -R option\n"); 3582f167a42Smrg } 3592f167a42Smrg else if (rootDir != NULL) { 3602f167a42Smrg uWarning("Multiple root directories specified\n"); 3612f167a42Smrg uAction("Using %s, ignoring %s\n", rootDir, argv[i]); 3622f167a42Smrg } 3632f167a42Smrg else 3642f167a42Smrg rootDir = &argv[i][2]; 3652f167a42Smrg } 3662f167a42Smrg else if (strcmp(argv[i], "-pict") == 0) { 3672f167a42Smrg if (++i >= argc) { 3682f167a42Smrg uWarning("No level of pictographs specified\n"); 3692f167a42Smrg uAction("Trailing \"-pict\" option ignored\n"); 3702f167a42Smrg } 3712f167a42Smrg else if (strcmp(argv[i], "none") == 0) 3722f167a42Smrg args.wantSymbols = NO_SYMBOLS; 3732f167a42Smrg else if (strcmp(argv[i], "common") == 0) 3742f167a42Smrg args.wantSymbols = COMMON_SYMBOLS; 3752f167a42Smrg else if (strcmp(argv[i], "all") == 0) 3762f167a42Smrg args.wantSymbols = ALL_SYMBOLS; 3772f167a42Smrg else if (outputFile != NULL) { 3782f167a42Smrg uWarning("Unknown pictograph level specified\n"); 3792f167a42Smrg uAction("Ignoring illegal value %s\n", argv[i]); 3802f167a42Smrg } 3812f167a42Smrg } 3822f167a42Smrg else if ((strcmp(argv[i], "-synch") == 0) || 3832f167a42Smrg (strcmp(argv[i], "-s") == 0)) { 3842f167a42Smrg synch = True; 3852f167a42Smrg } 3862f167a42Smrg else if (strcmp(argv[i], "-version") == 0) { 3872f167a42Smrg puts(PACKAGE_STRING); 3882f167a42Smrg exit(0); 3892f167a42Smrg } 3902f167a42Smrg else if (strcmp(argv[i], "-w") == 0) { 3912f167a42Smrg if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) { 3922f167a42Smrg warningLevel = 0; 3932f167a42Smrg } 3942f167a42Smrg else { 3952f167a42Smrg int itmp; 3962f167a42Smrg 3972f167a42Smrg if (sscanf(argv[++i], "%i", &itmp)) 3982f167a42Smrg warningLevel = itmp; 3992f167a42Smrg } 4002f167a42Smrg } 4012f167a42Smrg else { 4022f167a42Smrg uError("Unknown flag \"%s\" on command line\n", argv[i]); 4032f167a42Smrg Usage(argc, argv); 4042f167a42Smrg return False; 4052f167a42Smrg } 4060e20ee16Smrg } 4070e20ee16Smrg if (rootDir) { 4082f167a42Smrg if (warningLevel > 8) { 4092f167a42Smrg uWarning("Changing root directory to \"%s\"\n", rootDir); 4102f167a42Smrg } 4112f167a42Smrg if ((chdir(rootDir) < 0) && (warningLevel > 0)) { 4122f167a42Smrg uWarning("Couldn't change root directory to \"%s\"\n", rootDir); 4132f167a42Smrg uAction("Root directory (-R) option ignored\n"); 4142f167a42Smrg } 4150e20ee16Smrg } 4162f167a42Smrg if (outputFont != NULL) { 4172f167a42Smrg Bool ok; 4182f167a42Smrg FILE *file = NULL; 4192f167a42Smrg 4202f167a42Smrg if (outputFile == NULL) { 4212f167a42Smrg asprintf(&outputFile, "%s.pfa", outputFont); 4222f167a42Smrg } 4232f167a42Smrg else if (uStringEqual(outputFile, "-")) 4242f167a42Smrg file = stdout; 4252f167a42Smrg 4262f167a42Smrg if (file == NULL) 4272f167a42Smrg file = fopen(outputFile, "w"); 4282f167a42Smrg 4292f167a42Smrg if (!file) { 4302f167a42Smrg uError("Couldn't open \"%s\" to dump internal font \"%s\"\n", 4312f167a42Smrg outputFile, outputFont); 4322f167a42Smrg uAction("Exiting\n"); 4332f167a42Smrg exit(1); 4342f167a42Smrg } 4352f167a42Smrg ok = DumpInternalFont(file, outputFont); 4362f167a42Smrg if (file != stdout) 4372f167a42Smrg fclose(file); 4382f167a42Smrg if (!ok) { 4392f167a42Smrg uWarning("No internal font to dump\n"); 4402f167a42Smrg if (file != stdout) { 4412f167a42Smrg uAction("Removing \"%s\"\n", outputFile); 4422f167a42Smrg unlink(outputFile); 4432f167a42Smrg } 4442f167a42Smrg } 4452f167a42Smrg exit((ok != 0)); 4460e20ee16Smrg } 4472f167a42Smrg if (inputFile == NULL) { 4482f167a42Smrg uError("No input file specified\n"); 4492f167a42Smrg Usage(argc, argv); 4502f167a42Smrg return False; 4510e20ee16Smrg } 4522f167a42Smrg else if (uStringEqual(inputFile, "-")) { 4532f167a42Smrg /* Nothing */ 4540e20ee16Smrg } 4552f167a42Smrg else if (strchr(inputFile, ':') == NULL) { 4562f167a42Smrg size_t len = strlen(inputFile); 4572f167a42Smrg 4582f167a42Smrg if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) { 4592f167a42Smrg /* Nothing */ 4602f167a42Smrg } 4612f167a42Smrg else { 4622f167a42Smrg FILE *file; 4632f167a42Smrg 4642f167a42Smrg file = fopen(inputFile, "r"); 4652f167a42Smrg if (file) { 4662f167a42Smrg fclose(file); 4672f167a42Smrg } 4682f167a42Smrg else { 4692f167a42Smrg fprintf(stderr, "Cannot open \"%s\" for reading\n", inputFile); 4702f167a42Smrg return False; 4712f167a42Smrg } 4722f167a42Smrg } 4730e20ee16Smrg } 4740e20ee16Smrg else { 4752f167a42Smrg inDpyName = inputFile; 4762f167a42Smrg inputFile = NULL; 4770e20ee16Smrg } 4780e20ee16Smrg 4792f167a42Smrg if (outputFormat == WANT_DEFAULT) 4802f167a42Smrg outputFormat = WANT_PS_FILE; 4812f167a42Smrg if ((outputFile == NULL) && (inputFile != NULL) && 4822f167a42Smrg uStringEqual(inputFile, "-")) { 4832f167a42Smrg size_t len; 4842f167a42Smrg 4852f167a42Smrg len = strlen("stdin.eps") + 2; 4862f167a42Smrg outputFile = calloc(len, sizeof(char)); 4872f167a42Smrg 4882f167a42Smrg if (outputFile == NULL) { 4892f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 4902f167a42Smrg uAction("Exiting\n"); 4912f167a42Smrg exit(1); 4922f167a42Smrg } 4932f167a42Smrg if (args.wantEPS) 4942f167a42Smrg snprintf(outputFile, len, "stdin.eps"); 4952f167a42Smrg else 4962f167a42Smrg snprintf(outputFile, len, "stdin.ps"); 4970e20ee16Smrg } 4982f167a42Smrg else if ((outputFile == NULL) && (inputFile != NULL)) { 4992f167a42Smrg size_t len; 5002f167a42Smrg char *base, *ext; 5012f167a42Smrg 5022f167a42Smrg base = strrchr(inputFile, '/'); 5032f167a42Smrg if (base == NULL) 5042f167a42Smrg base = inputFile; 5052f167a42Smrg else 5062f167a42Smrg base++; 5072f167a42Smrg 5082f167a42Smrg len = strlen(base) + strlen("eps") + 2; 5092f167a42Smrg outputFile = calloc(len, sizeof(char)); 5102f167a42Smrg 5112f167a42Smrg if (outputFile == NULL) { 5122f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 5132f167a42Smrg uAction("Exiting\n"); 5142f167a42Smrg exit(1); 5152f167a42Smrg } 5162f167a42Smrg ext = strrchr(base, '.'); 5172f167a42Smrg if (ext == NULL) { 5182f167a42Smrg if (args.wantEPS) 5192f167a42Smrg snprintf(outputFile, len, "%s.eps", base); 5202f167a42Smrg else 5212f167a42Smrg snprintf(outputFile, len, "%s.ps", base); 5222f167a42Smrg } 5232f167a42Smrg else { 5242f167a42Smrg strcpy(outputFile, base); 5252f167a42Smrg if (args.wantEPS) 5262f167a42Smrg strcpy(&outputFile[ext - base + 1], "eps"); 5272f167a42Smrg else 5282f167a42Smrg strcpy(&outputFile[ext - base + 1], "ps"); 5292f167a42Smrg } 5300e20ee16Smrg } 5312f167a42Smrg else if (outputFile == NULL) { 5322f167a42Smrg size_t len; 5332f167a42Smrg char *ch, *name, buf[128]; 5342f167a42Smrg 5352f167a42Smrg if (inDpyName[0] == ':') 5362f167a42Smrg snprintf(name = buf, sizeof(buf), "server%s", inDpyName); 5372f167a42Smrg else 5382f167a42Smrg name = inDpyName; 5392f167a42Smrg 5402f167a42Smrg len = strlen(name) + strlen("eps") + 2; 5412f167a42Smrg outputFile = calloc(len, sizeof(char)); 5422f167a42Smrg 5432f167a42Smrg if (outputFile == NULL) { 5442f167a42Smrg uInternalError("Cannot allocate space for output file name\n"); 5452f167a42Smrg uAction("Exiting\n"); 5462f167a42Smrg exit(1); 5472f167a42Smrg } 5482f167a42Smrg strcpy(outputFile, name); 5492f167a42Smrg for (ch = outputFile; (*ch) != '\0'; ch++) { 5502f167a42Smrg if (*ch == ':') 5512f167a42Smrg *ch = '-'; 5522f167a42Smrg else if (*ch == '.') 5532f167a42Smrg *ch = '_'; 5542f167a42Smrg } 5552f167a42Smrg *ch++ = '.'; 5562f167a42Smrg if (args.wantEPS) 5572f167a42Smrg strcpy(ch, "eps"); 5582f167a42Smrg else 5592f167a42Smrg strcpy(ch, "ps"); 5600e20ee16Smrg } 5612f167a42Smrg else if (strchr(outputFile, ':') != NULL) { 5622f167a42Smrg outDpyName = outputFile; 5632f167a42Smrg outputFile = NULL; 5642f167a42Smrg outputFormat = WANT_X_SERVER; 5652f167a42Smrg uInternalError("Output to an X server not implemented yet\n"); 5662f167a42Smrg return False; 5670e20ee16Smrg } 5680e20ee16Smrg return True; 5690e20ee16Smrg} 5700e20ee16Smrg 5710e20ee16Smrgstatic Display * 5720e20ee16SmrgGetDisplay(char *program, char *dpyName) 5730e20ee16Smrg{ 5742f167a42Smrg int mjr, mnr, error; 5752f167a42Smrg Display *dpy; 5762f167a42Smrg 5772f167a42Smrg mjr = XkbMajorVersion; 5782f167a42Smrg mnr = XkbMinorVersion; 5792f167a42Smrg dpy = XkbOpenDisplay(dpyName, NULL, NULL, &mjr, &mnr, &error); 5802f167a42Smrg if (dpy == NULL) { 5812f167a42Smrg switch (error) { 5822f167a42Smrg case XkbOD_BadLibraryVersion: 5832f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 5842f167a42Smrg program, XkbMajorVersion, XkbMinorVersion); 5852f167a42Smrg uError("X library supports incompatible version %d.%02d\n", 5862f167a42Smrg mjr, mnr); 5872f167a42Smrg break; 5882f167a42Smrg case XkbOD_ConnectionRefused: 5892f167a42Smrg uError("Cannot open display \"%s\"\n", dpyName); 5902f167a42Smrg break; 5912f167a42Smrg case XkbOD_NonXkbServer: 5922f167a42Smrg uError("XKB extension not present on %s\n", dpyName); 5932f167a42Smrg break; 5942f167a42Smrg case XkbOD_BadServerVersion: 5952f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 5962f167a42Smrg program, XkbMajorVersion, XkbMinorVersion); 5972f167a42Smrg uError("Server %s uses incompatible version %d.%02d\n", 5982f167a42Smrg dpyName, mjr, mnr); 5992f167a42Smrg break; 6002f167a42Smrg default: 6012f167a42Smrg uInternalError("Unknown error %d from XkbOpenDisplay\n", error); 6022f167a42Smrg } 6030e20ee16Smrg } 6040e20ee16Smrg else if (synch) 6052f167a42Smrg XSynchronize(dpy, True); 6060e20ee16Smrg return dpy; 6070e20ee16Smrg} 6080e20ee16Smrg 6090e20ee16Smrg/***====================================================================***/ 6100e20ee16Smrg 6110e20ee16Smrg 6120e20ee16Smrgint 6130e20ee16Smrgmain(int argc, char *argv[]) 6140e20ee16Smrg{ 6152f167a42Smrg FILE *file; 6162f167a42Smrg int ok; 6172f167a42Smrg XkbFileInfo result; 6180e20ee16Smrg 6190e20ee16Smrg uSetErrorFile(NullString); 6202f167a42Smrg if (!parseArgs(argc, argv)) 6212f167a42Smrg exit(1); 6222f167a42Smrg file = NULL; 6230e20ee16Smrg XkbInitAtoms(NULL); 6240e20ee16Smrg/* XkbInitIncludePath(); */ 6252f167a42Smrg if (inputFile != NULL) { 6262f167a42Smrg if (uStringEqual(inputFile, "-")) { 6272f167a42Smrg static char in[] = "stdin"; 6282f167a42Smrg 6292f167a42Smrg file = stdin; 6302f167a42Smrg inputFile = in; 6312f167a42Smrg } 6322f167a42Smrg else { 6332f167a42Smrg file = fopen(inputFile, "r"); 6342f167a42Smrg } 6350e20ee16Smrg } 6362f167a42Smrg else if (inDpyName != NULL) { 6372f167a42Smrg inDpy = GetDisplay(argv[0], inDpyName); 6382f167a42Smrg if (!inDpy) { 6392f167a42Smrg uAction("Exiting\n"); 6402f167a42Smrg exit(1); 6412f167a42Smrg } 6420e20ee16Smrg } 6432f167a42Smrg if (outDpyName != NULL) { 6442f167a42Smrg uInternalError("Output to an X server not implemented yet\n"); 6452f167a42Smrg outDpy = GetDisplay(argv[0], outDpyName); 6462f167a42Smrg if (!outDpy) { 6472f167a42Smrg uAction("Exiting\n"); 6482f167a42Smrg exit(1); 6492f167a42Smrg } 6500e20ee16Smrg } 6512f167a42Smrg if ((inDpy == NULL) && (outDpy == NULL)) { 6522f167a42Smrg int mjr, mnr; 6532f167a42Smrg 6542f167a42Smrg mjr = XkbMajorVersion; 6552f167a42Smrg mnr = XkbMinorVersion; 6562f167a42Smrg if (!XkbLibraryVersion(&mjr, &mnr)) { 6572f167a42Smrg uInformation("%s was compiled with XKB version %d.%02d\n", 6582f167a42Smrg argv[0], XkbMajorVersion, XkbMinorVersion); 6592f167a42Smrg uError("X library supports incompatible version %d.%02d\n", 6602f167a42Smrg mjr, mnr); 6612f167a42Smrg uAction("Exiting\n"); 6622f167a42Smrg exit(1); 6632f167a42Smrg } 6640e20ee16Smrg } 6652f167a42Smrg ok = True; 6660e20ee16Smrg if (file) { 6672f167a42Smrg unsigned tmp; 6682f167a42Smrg 6692f167a42Smrg bzero((char *) &result, sizeof(result)); 6702f167a42Smrg if ((result.xkb = XkbAllocKeyboard()) == NULL) { 6712f167a42Smrg uFatalError("Cannot allocate keyboard description\n"); 6722f167a42Smrg /* NOTREACHED */ 6732f167a42Smrg } 6742f167a42Smrg tmp = XkmReadFile(file, XkmGeometryMask, XkmKeymapLegal, &result); 6752f167a42Smrg if ((tmp & XkmGeometryMask) != 0) { 6762f167a42Smrg uError("Couldn't read geometry from XKM file \"%s\"\n", inputFile); 6772f167a42Smrg uAction("Exiting\n"); 6782f167a42Smrg ok = False; 6792f167a42Smrg } 6802f167a42Smrg if ((tmp & XkmKeyNamesMask) != 0) 6812f167a42Smrg args.wantKeycodes = False; 6822f167a42Smrg if (args.label == LABEL_AUTO) { 6832f167a42Smrg if (result.defined & XkmSymbolsMask) 6842f167a42Smrg args.label = LABEL_SYMBOLS; 6852f167a42Smrg else if (result.defined & XkmKeyNamesMask) 6862f167a42Smrg args.label = LABEL_KEYCODE; 6872f167a42Smrg else 6882f167a42Smrg args.label = LABEL_KEYNAME; 6892f167a42Smrg } 6902f167a42Smrg else if ((args.label == LABEL_KEYCODE) && 6912f167a42Smrg ((tmp & XkmKeyNamesMask) != 0)) { 6922f167a42Smrg uError("XKM file \"%s\" doesn't have keycodes\n", inputFile); 6932f167a42Smrg uAction("Cannot label keys as requested. Exiting\n"); 6942f167a42Smrg ok = False; 6952f167a42Smrg } 6962f167a42Smrg else if ((args.label == LABEL_SYMBOLS) && ((tmp & XkmSymbolsMask) != 0)) { 6972f167a42Smrg uError("XKM file \"%s\" doesn't have symbols\n", inputFile); 6982f167a42Smrg uAction("Cannot label keys as requested. Exiting\n"); 6992f167a42Smrg ok = False; 7002f167a42Smrg } 7010e20ee16Smrg } 7022f167a42Smrg else if (inDpy != NULL) { 7032f167a42Smrg bzero((char *) &result, sizeof(result)); 7042f167a42Smrg result.type = XkmKeymapFile; 7052f167a42Smrg result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask, XkbUseCoreKbd); 7062f167a42Smrg if (result.xkb == NULL) 7072f167a42Smrg uWarning("Cannot load keyboard description\n"); 7082f167a42Smrg if (XkbGetNames(inDpy, XkbAllNamesMask, result.xkb) != Success) 7092f167a42Smrg uWarning("Cannot load names\n"); 7102f167a42Smrg if (XkbGetGeometry(inDpy, result.xkb) != Success) { 7112f167a42Smrg uFatalError("Cannot load geometry for %s\n", inDpyName); 7122f167a42Smrg } 7132f167a42Smrg if (args.label == LABEL_AUTO) 7142f167a42Smrg args.label = LABEL_SYMBOLS; 7150e20ee16Smrg } 7160e20ee16Smrg else { 7172f167a42Smrg fprintf(stderr, "Cannot open \"%s\" to read geometry\n", inputFile); 7182f167a42Smrg ok = 0; 7190e20ee16Smrg } 7200e20ee16Smrg if (ok) { 7212f167a42Smrg FILE *out = NULL; 7222f167a42Smrg 7232f167a42Smrg if (setlocale(LC_ALL, (wantLocale)) == NULL) { 7242f167a42Smrg if (wantLocale != NULL) { 7252f167a42Smrg uWarning("Couldn't change to locale %s\n", wantLocale); 7262f167a42Smrg uAction("Using \"C\" locale, instead\n"); 7272f167a42Smrg } 7282f167a42Smrg } 7292f167a42Smrg /* need C numerics so decimal point doesn't get screwed up */ 7302f167a42Smrg setlocale(LC_NUMERIC, "C"); 7312f167a42Smrg if ((inDpy != outDpy) && 7322f167a42Smrg (XkbChangeKbdDisplay(outDpy, &result) != Success)) { 7332f167a42Smrg uInternalError("Error converting keyboard display from %s to %s\n", 7342f167a42Smrg inDpyName, outDpyName); 7352f167a42Smrg exit(1); 7362f167a42Smrg } 7372f167a42Smrg if (outputFile != NULL) { 7382f167a42Smrg if (uStringEqual(outputFile, "-")) { 7392f167a42Smrg static char of[] = "stdout"; 7402f167a42Smrg 7412f167a42Smrg out = stdout; 7422f167a42Smrg outputFile = of; 7432f167a42Smrg } 7442f167a42Smrg else { 7452f167a42Smrg out = fopen(outputFile, "w"); 7462f167a42Smrg if (out == NULL) { 7472f167a42Smrg uError("Cannot open \"%s\" to write keyboard description\n", 7482f167a42Smrg outputFile); 7492f167a42Smrg uAction("Exiting\n"); 7502f167a42Smrg exit(1); 7512f167a42Smrg } 7522f167a42Smrg } 7532f167a42Smrg } 7542f167a42Smrg switch (outputFormat) { 7552f167a42Smrg case WANT_PS_FILE: 7562f167a42Smrg ok = GeometryToPostScript(out, &result, &args); 7572f167a42Smrg break; 7582f167a42Smrg case WANT_X_SERVER: 7592f167a42Smrg uInternalError("Output to X server not implemented yet\n"); 7602f167a42Smrg break; 7612f167a42Smrg default: 7622f167a42Smrg uInternalError("Unknown output format %d\n", outputFormat); 7632f167a42Smrg uAction("No output file created\n"); 7642f167a42Smrg ok = False; 7652f167a42Smrg break; 7662f167a42Smrg } 7672f167a42Smrg if (!ok) { 7682f167a42Smrg uError("Error creating output file\n"); 7692f167a42Smrg } 7700e20ee16Smrg } 7712f167a42Smrg if (inDpy) 7722f167a42Smrg XCloseDisplay(inDpy); 7732f167a42Smrg inDpy = NULL; 7740e20ee16Smrg if (outDpy) 7752f167a42Smrg XCloseDisplay(outDpy); 7762f167a42Smrg return (ok == 0); 7770e20ee16Smrg} 778