xkbprint.c revision 0e20ee16
10e20ee16Smrg/* $Xorg: xkbprint.c,v 1.4 2000/08/17 19:54:50 cpqbld Exp $ */
20e20ee16Smrg/************************************************************
30e20ee16Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
40e20ee16Smrg
50e20ee16Smrg Permission to use, copy, modify, and distribute this
60e20ee16Smrg software and its documentation for any purpose and without
70e20ee16Smrg fee is hereby granted, provided that the above copyright
80e20ee16Smrg notice appear in all copies and that both that copyright
90e20ee16Smrg notice and this permission notice appear in supporting
100e20ee16Smrg documentation, and that the name of Silicon Graphics not be
110e20ee16Smrg used in advertising or publicity pertaining to distribution
120e20ee16Smrg of the software without specific prior written permission.
130e20ee16Smrg Silicon Graphics makes no representation about the suitability
140e20ee16Smrg of this software for any purpose. It is provided "as is"
150e20ee16Smrg without any express or implied warranty.
160e20ee16Smrg
170e20ee16Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
180e20ee16Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
190e20ee16Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
200e20ee16Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
210e20ee16Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
220e20ee16Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
230e20ee16Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
240e20ee16Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
250e20ee16Smrg
260e20ee16Smrg ********************************************************/
270e20ee16Smrg/* $XFree86: xc/programs/xkbprint/xkbprint.c,v 3.10 2003/05/27 22:27:07 tsi Exp $ */
280e20ee16Smrg
290e20ee16Smrg#include <stdio.h>
300e20ee16Smrg#include <ctype.h>
310e20ee16Smrg#include <X11/Xlocale.h>
320e20ee16Smrg#include <X11/X.h>
330e20ee16Smrg#include <X11/Xlib.h>
340e20ee16Smrg#include <X11/XKBlib.h>
350e20ee16Smrg#include <X11/extensions/XKBgeom.h>
360e20ee16Smrg#include <X11/extensions/XKM.h>
370e20ee16Smrg#include <X11/extensions/XKBfile.h>
380e20ee16Smrg#include <X11/keysym.h>
390e20ee16Smrg
400e20ee16Smrg#if defined(sgi)
410e20ee16Smrg#include <malloc.h>
420e20ee16Smrg#endif
430e20ee16Smrg
440e20ee16Smrg#define	DEBUG_VAR_NOT_LOCAL
450e20ee16Smrg#define	DEBUG_VAR debugFlags
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#define	INPUT_UNKNOWN	0
590e20ee16Smrg#define	INPUT_XKB	1
600e20ee16Smrg#define	INPUT_XKM	2
610e20ee16Smrg
620e20ee16Smrg#ifdef notyet
630e20ee16Smrgstatic char *fileTypeExt[] = {
640e20ee16Smrg	"XXX",
650e20ee16Smrg	"xkm",
660e20ee16Smrg	"xkb"
670e20ee16Smrg};
680e20ee16Smrg#endif
690e20ee16Smrg
700e20ee16Smrgstatic	unsigned	outputFormat= WANT_DEFAULT;
710e20ee16Smrgstatic	char *		wantLocale= "C";
720e20ee16Smrgstatic	char *		rootDir;
730e20ee16Smrgstatic	char *		inputFile;
740e20ee16Smrgstatic	char *		outputFile;
750e20ee16Smrgstatic	char *		outputFont= NULL;
760e20ee16Smrgstatic	char *		inDpyName,*outDpyName;
770e20ee16Smrgstatic	Display *	inDpy;
780e20ee16Smrgstatic	Display *	outDpy;
790e20ee16Smrg#ifdef NOTYET
800e20ee16Smrgstatic	Bool		computeDflts= False;
810e20ee16Smrg#endif
820e20ee16Smrgstatic	XKBPrintArgs	args;
830e20ee16Smrg	unsigned	warningLevel= 5;
840e20ee16Smrg	Bool		synch;
850e20ee16Smrg
860e20ee16Smrg/***====================================================================***/
870e20ee16Smrg
880e20ee16Smrgstatic void
890e20ee16SmrgUsage(int argc, char *argv[])
900e20ee16Smrg{
910e20ee16Smrg    fprintf(stderr,"Usage: %s [options] input-file [ output-file ]\n",argv[0]);
920e20ee16Smrg    fprintf(stderr,"Legal options:\n");
930e20ee16Smrg    fprintf(stderr,"-?,-help      Print this message\n");
940e20ee16Smrg    fprintf(stderr,"-color        Use colors from geometry\n");
950e20ee16Smrg#ifdef DEBUG
960e20ee16Smrg    fprintf(stderr,"-d [flags]    Report debugging information\n");
970e20ee16Smrg#endif
980e20ee16Smrg    fprintf(stderr,"-dflts        Compute defaults for missing components\n");
990e20ee16Smrg    fprintf(stderr,"-diffs        Only show explicit key definitions\n");
1000e20ee16Smrg    fprintf(stderr,"-eps          Generate an EPS file\n");
1010e20ee16Smrg    fprintf(stderr,"-fit          Fit keyboard image on page (default)\n");
1020e20ee16Smrg    fprintf(stderr,"-full         Print keyboard image full sized\n");
1030e20ee16Smrg    fprintf(stderr,"-grid <n>     Print a grid with <n> mm resolution\n");
1040e20ee16Smrg    fprintf(stderr,"-if <name>    Specifies the name of an internal font to dump\n");
1050e20ee16Smrg#ifdef DEBUG
1060e20ee16Smrg    fprintf(stderr,"-I[<dir>]     Specifies a top level directory\n");
1070e20ee16Smrg    fprintf(stderr,"              for include directives.  You can\n");
1080e20ee16Smrg    fprintf(stderr,"              specify multiple directories.\n");
1090e20ee16Smrg#endif
1100e20ee16Smrg    fprintf(stderr,"-kc           Also print keycodes, if possible\n");
1110e20ee16Smrg    fprintf(stderr,"-label <what> Specifies the label to be drawn on keys\n");
1120e20ee16Smrg    fprintf(stderr,"              Legal values for <what> are:\n");
1130e20ee16Smrg    fprintf(stderr,"                  none,name,code,symbols\n");
1140e20ee16Smrg    fprintf(stderr,"-lc <locale>  Use <locale> for fonts and symbols\n");
1150e20ee16Smrg    fprintf(stderr,"-level1       Use level 1 PostScript (default)\n");
1160e20ee16Smrg    fprintf(stderr,"-level2       Use level 2 PostScript\n");
1170e20ee16Smrg    fprintf(stderr,"-lg <num>     Use keyboard group <num> to print labels\n");
1180e20ee16Smrg    fprintf(stderr,"-ll <num>     Use shift level <num> to print labels\n");
1190e20ee16Smrg    fprintf(stderr,"-mono         Ignore colors from geometry (default)\n");
1200e20ee16Smrg    fprintf(stderr,"-n <num>      Print <num> copies (default 1)\n");
1210e20ee16Smrg    fprintf(stderr,"-nkg <num>    Number of groups to print on each key\n");
1220e20ee16Smrg    fprintf(stderr,"-nokc         Don't print keycodes, even if possible\n");
1230e20ee16Smrg    fprintf(stderr,"-npk <num>    Number of keyboards to print on each page\n");
1240e20ee16Smrg    fprintf(stderr,"-ntg <num>    Total number of groups to print\n");
1250e20ee16Smrg    fprintf(stderr,"-o <file>     Specifies output file name\n");
1260e20ee16Smrg    fprintf(stderr,"-R[<DIR>]     Specifies the root directory for relative\n");
1270e20ee16Smrg    fprintf(stderr,"              path names\n");
1280e20ee16Smrg    fprintf(stderr,"-pict <what>  Specifies use of pictographs instead of\n");
1290e20ee16Smrg    fprintf(stderr,"              keysym names where available, <what> can\n");
1300e20ee16Smrgfprintf(stderr,"              be \"all\", \"none\" or \"common\" (default)\n");
1310e20ee16Smrg    fprintf(stderr,"-synch        Force synchronization\n");
1320e20ee16Smrg    fprintf(stderr,"-w <lvl>      Set warning level (0=none, 10=all)\n");
1330e20ee16Smrg}
1340e20ee16Smrg
1350e20ee16Smrg/***====================================================================***/
1360e20ee16Smrg
1370e20ee16Smrgstatic Bool
1380e20ee16SmrgparseArgs(int argc, char *argv[])
1390e20ee16Smrg{
1400e20ee16Smrgregister int i;
1410e20ee16Smrg
1420e20ee16Smrg    args.copies=	1;
1430e20ee16Smrg    args.grid=		0;
1440e20ee16Smrg    args.level1=	True;
1450e20ee16Smrg    args.scaleToFit=	True;
1460e20ee16Smrg    args.wantColor=	False;
1470e20ee16Smrg    args.wantSymbols=	COMMON_SYMBOLS;
1480e20ee16Smrg    args.wantKeycodes=	True;
1490e20ee16Smrg    args.wantDiffs=	False;
1500e20ee16Smrg    args.wantEPS=	False;
1510e20ee16Smrg    args.label=		LABEL_AUTO;
1520e20ee16Smrg    args.baseLabelGroup=0;
1530e20ee16Smrg    args.nLabelGroups=	1;
1540e20ee16Smrg    args.nTotalGroups=	0;
1550e20ee16Smrg    args.nKBPerPage=	0;
1560e20ee16Smrg    args.labelLevel=	0;
1570e20ee16Smrg    for (i=1;i<argc;i++) {
1580e20ee16Smrg	if ((argv[i][0]!='-')||(uStringEqual(argv[i],"-"))) {
1590e20ee16Smrg	    if (inputFile==NULL) {
1600e20ee16Smrg		inputFile= argv[i];
1610e20ee16Smrg	    }
1620e20ee16Smrg	    else if (outputFile==NULL) {
1630e20ee16Smrg		outputFile= argv[i];
1640e20ee16Smrg	    }
1650e20ee16Smrg	    else {
1660e20ee16Smrg		uWarning("Too many file names on command line\n");
1670e20ee16Smrg		uAction("Compiling %s, writing to %s, ignoring %s\n",
1680e20ee16Smrg					inputFile,outputFile,argv[i]);
1690e20ee16Smrg	    }
1700e20ee16Smrg	}
1710e20ee16Smrg	else if ((strcmp(argv[i],"-?")==0)||(strcmp(argv[i],"-help")==0)) {
1720e20ee16Smrg	    Usage(argc,argv);
1730e20ee16Smrg	    exit(0);
1740e20ee16Smrg	}
1750e20ee16Smrg	else if (strcmp(argv[i],"-color")==0) {
1760e20ee16Smrg	    args.wantColor= True;
1770e20ee16Smrg	}
1780e20ee16Smrg#ifdef DEBUG
1790e20ee16Smrg	else if (strcmp(argv[i],"-d")==0) {
1800e20ee16Smrg	    if ((i>=(argc-1))||(!isdigit(argv[i+1][0]))) {
1810e20ee16Smrg		debugFlags= 1;
1820e20ee16Smrg	    }
1830e20ee16Smrg	    else {
1840e20ee16Smrg		sscanf(argv[++i],"%i",&debugFlags);
1850e20ee16Smrg	    }
1860e20ee16Smrg	    uInformation("Setting debug flags to %d\n",debugFlags);
1870e20ee16Smrg	}
1880e20ee16Smrg#endif
1890e20ee16Smrg	else if (strcmp(argv[i],"-dflts")==0) {
1900e20ee16Smrg#ifdef NOTYET
1910e20ee16Smrg	    computeDflts= True;
1920e20ee16Smrg#endif
1930e20ee16Smrg	    uWarning("Compute defaults not implemented yet\n");
1940e20ee16Smrg	}
1950e20ee16Smrg	else if (strcmp(argv[i],"-diffs")==0) {
1960e20ee16Smrg	    args.wantDiffs= True;
1970e20ee16Smrg	}
1980e20ee16Smrg	else if (strcmp(argv[i],"-eps")==0) {
1990e20ee16Smrg	    args.wantEPS= True;
2000e20ee16Smrg	}
2010e20ee16Smrg	else if (strcmp(argv[i],"-fit")==0) {
2020e20ee16Smrg	    args.scaleToFit= True;
2030e20ee16Smrg	}
2040e20ee16Smrg	else if (strcmp(argv[i],"-full")==0) {
2050e20ee16Smrg	    args.scaleToFit= False;
2060e20ee16Smrg	}
2070e20ee16Smrg	else if (strcmp(argv[i],"-grid")==0) {
2080e20ee16Smrg	    int tmp;
2090e20ee16Smrg	    if (++i>=argc) {
2100e20ee16Smrg		uWarning("Grid frequency not specified\n");
2110e20ee16Smrg		uAction("Trailing \"-grid\" option ignored\n");
2120e20ee16Smrg	    }
2130e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)) {
2140e20ee16Smrg		uWarning("Grid frequency must be an integer > zero\n");
2150e20ee16Smrg		uAction("Illegal frequency %d ignored\n",tmp);
2160e20ee16Smrg	    }
2170e20ee16Smrg	    else args.grid= tmp;
2180e20ee16Smrg	}
2190e20ee16Smrg#ifdef NOTYET
2200e20ee16Smrg	else if (strncmp(argv[i],"-I",2)==0) {
2210e20ee16Smrg	    if (!XkbAddDirectoryToPath(&argv[i][2])) {
2220e20ee16Smrg		uAction("Exiting\n");
2230e20ee16Smrg		exit(1);
2240e20ee16Smrg	    }
2250e20ee16Smrg	    uInternalError("Includes not implemented yet\n");
2260e20ee16Smrg	}
2270e20ee16Smrg#endif
2280e20ee16Smrg	else if (strcmp(argv[i],"-if")==0) {
2290e20ee16Smrg	    if (++i>=argc) {
2300e20ee16Smrg		uWarning("Internal Font name not specified\n");
2310e20ee16Smrg		uAction("Trailing \"-if\" option ignored\n");
2320e20ee16Smrg	    }
2330e20ee16Smrg	    else outputFont= argv[i];
2340e20ee16Smrg	}
2350e20ee16Smrg	else if (strcmp(argv[i],"-kc")==0) {
2360e20ee16Smrg	    args.wantKeycodes= True;
2370e20ee16Smrg	}
2380e20ee16Smrg	else if (strcmp(argv[i],"-label")==0) {
2390e20ee16Smrg	    if (++i>=argc) {
2400e20ee16Smrg		uWarning("Label type not specified\n");
2410e20ee16Smrg		uAction("Trailing \"-label\" option ignored\n");
2420e20ee16Smrg	    }
2430e20ee16Smrg	    else if (uStrCaseEqual(argv[i],"none"))
2440e20ee16Smrg		args.label= LABEL_NONE;
2450e20ee16Smrg	    else if (uStrCaseEqual(argv[i],"name"))
2460e20ee16Smrg		args.label= LABEL_KEYNAME;
2470e20ee16Smrg	    else if (uStrCaseEqual(argv[i],"code"))
2480e20ee16Smrg		args.label= LABEL_KEYCODE;
2490e20ee16Smrg	    else if (uStrCaseEqual(argv[i],"symbols"))
2500e20ee16Smrg		args.label= LABEL_SYMBOLS;
2510e20ee16Smrg	    else {
2520e20ee16Smrg		uWarning("Unknown label type \"%s\" specified\n",argv[i]);
2530e20ee16Smrg		uAction("Ignored\n");
2540e20ee16Smrg	    }
2550e20ee16Smrg	}
2560e20ee16Smrg	else if (strcmp(argv[i],"-lc")==0) {
2570e20ee16Smrg	    if (++i>=argc) {
2580e20ee16Smrg		uWarning("Locale not specified\n");
2590e20ee16Smrg		uAction("Trailing \"-lc\" option ignored\n");
2600e20ee16Smrg	    }
2610e20ee16Smrg	    else wantLocale= argv[i];
2620e20ee16Smrg	}
2630e20ee16Smrg	else if (strcmp(argv[i],"-lg")==0) {
2640e20ee16Smrg	    int tmp;
2650e20ee16Smrg	    if (++i>=argc) {
2660e20ee16Smrg		uWarning("Label group not specified\n");
2670e20ee16Smrg		uAction("Trailing \"-lg\" option ignored\n");
2680e20ee16Smrg	    }
2690e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)||(tmp>4)) {
2700e20ee16Smrg		uWarning("Label group must be an integer in the range 1..4\n");
2710e20ee16Smrg		uAction("Illegal group %d ignored\n",tmp);
2720e20ee16Smrg	    }
2730e20ee16Smrg	    else args.baseLabelGroup= tmp-1;
2740e20ee16Smrg	}
2750e20ee16Smrg	else if (strcmp(argv[i],"-ll")==0) {
2760e20ee16Smrg	    int tmp;
2770e20ee16Smrg	    if (++i>=argc) {
2780e20ee16Smrg		uWarning("Label level not specified\n");
2790e20ee16Smrg		uAction("Trailing \"-ll\" option ignored\n");
2800e20ee16Smrg	    }
2810e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)||(tmp>255)) {
2820e20ee16Smrg		uWarning("Label level must be in the range 1..255\n");
2830e20ee16Smrg		uAction("Illegal level %d ignored\n",tmp);
2840e20ee16Smrg	    }
2850e20ee16Smrg	    else args.labelLevel= tmp-1;
2860e20ee16Smrg	}
2870e20ee16Smrg	else if (strcmp(argv[i],"-level1")==0)
2880e20ee16Smrg	    args.level1= True;
2890e20ee16Smrg	else if (strcmp(argv[i],"-level2")==0)
2900e20ee16Smrg	    args.level1= False;
2910e20ee16Smrg	else if (strcmp(argv[i],"-mono")==0) {
2920e20ee16Smrg	    args.wantColor= False;
2930e20ee16Smrg	}
2940e20ee16Smrg	else if (strcmp(argv[i],"-n")==0) {
2950e20ee16Smrg	    int tmp;
2960e20ee16Smrg	    if (++i>=argc) {
2970e20ee16Smrg		uWarning("Number of copies not specified\n");
2980e20ee16Smrg		uAction("Trailing \"-n\" option ignored\n");
2990e20ee16Smrg	    }
3000e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)) {
3010e20ee16Smrg		uWarning("Number of copies must be an integer > zero\n");
3020e20ee16Smrg		uAction("Illegal count %d ignored\n",tmp);
3030e20ee16Smrg	    }
3040e20ee16Smrg	    else args.copies= tmp;
3050e20ee16Smrg	}
3060e20ee16Smrg	else if (strcmp(argv[i],"-nokc")==0) {
3070e20ee16Smrg	    args.wantKeycodes= False;
3080e20ee16Smrg	}
3090e20ee16Smrg	else if (strcmp(argv[i],"-nkg")==0) {
3100e20ee16Smrg	    int tmp;
3110e20ee16Smrg	    if (++i>=argc) {
3120e20ee16Smrg		uWarning("Number of groups per key not specified\n");
3130e20ee16Smrg		uAction("Trailing \"-nkg\" option ignored\n");
3140e20ee16Smrg	    }
3150e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)||(tmp>2)) {
3160e20ee16Smrg		uWarning("Groups per key must be in the range 1..2\n");
3170e20ee16Smrg		uAction("Illegal number of groups %d ignored\n",tmp);
3180e20ee16Smrg	    }
3190e20ee16Smrg	    else args.nLabelGroups= tmp;
3200e20ee16Smrg	}
3210e20ee16Smrg	else if (strcmp(argv[i],"-npk")==0) {
3220e20ee16Smrg	    int tmp;
3230e20ee16Smrg	    if (++i>=argc) {
3240e20ee16Smrg		uWarning("Number of keyboards per page not specified\n");
3250e20ee16Smrg		uAction("Trailing \"-npk\" option ignored\n");
3260e20ee16Smrg	    }
3270e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)||(tmp>2)) {
3280e20ee16Smrg		uWarning("Keyboards per page must be in the range 1..2\n");
3290e20ee16Smrg		uAction("Illegal number of keyboards %d ignored\n",tmp);
3300e20ee16Smrg	    }
3310e20ee16Smrg	    else args.nKBPerPage= tmp;
3320e20ee16Smrg	}
3330e20ee16Smrg	else if (strcmp(argv[i],"-ntg")==0) {
3340e20ee16Smrg	    int tmp;
3350e20ee16Smrg	    if (++i>=argc) {
3360e20ee16Smrg		uWarning("Total number of groups not specified\n");
3370e20ee16Smrg		uAction("Trailing \"-ntg\" option ignored\n");
3380e20ee16Smrg	    }
3390e20ee16Smrg	    else if ((sscanf(argv[i],"%i",&tmp)!=1)||(tmp<1)||(tmp>4)) {
3400e20ee16Smrg		uWarning("Total number of groups must be in the range 1..4\n");
3410e20ee16Smrg		uAction("Illegal number of groups %d ignored\n",tmp);
3420e20ee16Smrg	    }
3430e20ee16Smrg	    else args.nTotalGroups= tmp;
3440e20ee16Smrg	}
3450e20ee16Smrg	else if (strcmp(argv[i],"-o")==0) {
3460e20ee16Smrg	    if (++i>=argc) {
3470e20ee16Smrg		uWarning("No output file specified\n");
3480e20ee16Smrg		uAction("Trailing \"-o\" option ignored\n");
3490e20ee16Smrg	    }
3500e20ee16Smrg	    else if (outputFile!=NULL) {
3510e20ee16Smrg		uWarning("Multiple output files specified\n");
3520e20ee16Smrg		uAction("Compiling %s, ignoring %s\n",outputFile,argv[i]);
3530e20ee16Smrg	    }
3540e20ee16Smrg	    else outputFile= argv[i];
3550e20ee16Smrg	}
3560e20ee16Smrg	else if (strncmp(argv[i],"-R",2)==0) {
3570e20ee16Smrg	    if (argv[i][2]=='\0') {
3580e20ee16Smrg		uWarning("No root directory specified\n");
3590e20ee16Smrg		uAction("Ignoring -R option\n");
3600e20ee16Smrg	    }
3610e20ee16Smrg	    else if (rootDir!=NULL) {
3620e20ee16Smrg		uWarning("Multiple root directories specified\n");
3630e20ee16Smrg		uAction("Using %s, ignoring %s\n",rootDir,argv[i]);
3640e20ee16Smrg	    }
3650e20ee16Smrg	    else rootDir= &argv[i][2];
3660e20ee16Smrg	}
3670e20ee16Smrg	else if (strcmp(argv[i],"-pict")==0) {
3680e20ee16Smrg	    if (++i>=argc) {
3690e20ee16Smrg		uWarning("No level of pictographs specified\n");
3700e20ee16Smrg		uAction("Trailing \"-pict\" option ignored\n");
3710e20ee16Smrg	    }
3720e20ee16Smrg	    else if (strcmp(argv[i],"none")==0)
3730e20ee16Smrg		args.wantSymbols= NO_SYMBOLS;
3740e20ee16Smrg	    else if (strcmp(argv[i],"common")==0)
3750e20ee16Smrg		args.wantSymbols= COMMON_SYMBOLS;
3760e20ee16Smrg	    else if (strcmp(argv[i],"all")==0)
3770e20ee16Smrg		args.wantSymbols= ALL_SYMBOLS;
3780e20ee16Smrg	    else if (outputFile!=NULL) {
3790e20ee16Smrg		uWarning("Unknown pictograph level specified\n");
3800e20ee16Smrg		uAction("Ignoring illegal value %s\n",argv[i]);
3810e20ee16Smrg	    }
3820e20ee16Smrg	}
3830e20ee16Smrg	else if ((strcmp(argv[i],"-synch")==0)||(strcmp(argv[i],"-s")==0)) {
3840e20ee16Smrg	    synch= True;
3850e20ee16Smrg	}
3860e20ee16Smrg	else if (strcmp(argv[i],"-w")==0) {
3870e20ee16Smrg	    if ((i>=(argc-1))||(!isdigit(argv[i+1][0]))) {
3880e20ee16Smrg		warningLevel= 0;
3890e20ee16Smrg	    }
3900e20ee16Smrg	    else {
3910e20ee16Smrg		int itmp;
3920e20ee16Smrg		if (sscanf(argv[++i],"%i",&itmp))
3930e20ee16Smrg		    warningLevel = itmp;
3940e20ee16Smrg	    }
3950e20ee16Smrg	}
3960e20ee16Smrg	else {
3970e20ee16Smrg	    uError("Unknown flag \"%s\" on command line\n",argv[i]);
3980e20ee16Smrg	    Usage(argc,argv);
3990e20ee16Smrg	    return False;
4000e20ee16Smrg	}
4010e20ee16Smrg    }
4020e20ee16Smrg    if (rootDir) {
4030e20ee16Smrg	if (warningLevel>8) {
4040e20ee16Smrg	    uWarning("Changing root directory to \"%s\"\n",rootDir);
4050e20ee16Smrg	}
4060e20ee16Smrg	if ((chdir(rootDir)<0) && (warningLevel>0)) {
4070e20ee16Smrg	    uWarning("Couldn't change root directory to \"%s\"\n",rootDir);
4080e20ee16Smrg	    uAction("Root directory (-R) option ignored\n");
4090e20ee16Smrg	}
4100e20ee16Smrg    }
4110e20ee16Smrg    if (outputFont!=NULL) {
4120e20ee16Smrg	Bool  ok;
4130e20ee16Smrg	FILE *file= NULL;
4140e20ee16Smrg
4150e20ee16Smrg	if (outputFile==NULL) {
4160e20ee16Smrg	    outputFile= uAlloc(strlen(outputFont)+5);
4170e20ee16Smrg	    sprintf(outputFile,"%s.pfa",outputFont);
4180e20ee16Smrg	}
4190e20ee16Smrg	else if (uStringEqual(outputFile,"-"))
4200e20ee16Smrg	    file= stdout;
4210e20ee16Smrg
4220e20ee16Smrg	if (file==NULL)
4230e20ee16Smrg	    file= fopen(outputFile,"w");
4240e20ee16Smrg
4250e20ee16Smrg	if (!file) {
4260e20ee16Smrg	    uError("Couldn't open \"%s\" to dump internal font \"%s\"\n",
4270e20ee16Smrg						outputFile,outputFont);
4280e20ee16Smrg	    uAction("Exiting\n");
4290e20ee16Smrg	    exit(1);
4300e20ee16Smrg	}
4310e20ee16Smrg	ok= DumpInternalFont(file,outputFont);
4320e20ee16Smrg	if (file!=stdout)
4330e20ee16Smrg	    fclose(file);
4340e20ee16Smrg	if (!ok) {
4350e20ee16Smrg	    uWarning("No internal font to dump\n");
4360e20ee16Smrg	    if (file!=stdout) {
4370e20ee16Smrg		uAction("Removing \"%s\"\n",outputFile);
4380e20ee16Smrg		unlink(outputFile);
4390e20ee16Smrg	    }
4400e20ee16Smrg	}
4410e20ee16Smrg	exit((ok!=0));
4420e20ee16Smrg    }
4430e20ee16Smrg    if (inputFile==NULL) {
4440e20ee16Smrg	uError("No input file specified\n");
4450e20ee16Smrg	Usage(argc,argv);
4460e20ee16Smrg	return False;
4470e20ee16Smrg    }
4480e20ee16Smrg    else if (uStringEqual(inputFile,"-")) {
4490e20ee16Smrg	/* Nothing */
4500e20ee16Smrg    }
4510e20ee16Smrg    else if (strchr(inputFile,':')==0) {
4520e20ee16Smrg	int	len= strlen(inputFile);
4530e20ee16Smrg	if ((len>4)&&(strcmp(&inputFile[len-4],".xkm")==0)) {
4540e20ee16Smrg	    /* Nothing */
4550e20ee16Smrg	}
4560e20ee16Smrg	else {
4570e20ee16Smrg	    FILE *file;
4580e20ee16Smrg	    file= fopen(inputFile,"r");
4590e20ee16Smrg	    if (file) {
4600e20ee16Smrg		fclose(file);
4610e20ee16Smrg	    }
4620e20ee16Smrg	    else {
4630e20ee16Smrg		fprintf(stderr,"Cannot open \"%s\" for reading\n",inputFile);
4640e20ee16Smrg		return False;
4650e20ee16Smrg	    }
4660e20ee16Smrg	}
4670e20ee16Smrg    }
4680e20ee16Smrg    else {
4690e20ee16Smrg	inDpyName= inputFile;
4700e20ee16Smrg	inputFile= NULL;
4710e20ee16Smrg    }
4720e20ee16Smrg
4730e20ee16Smrg    if (outputFormat==WANT_DEFAULT)
4740e20ee16Smrg	outputFormat= WANT_PS_FILE;
4750e20ee16Smrg    if ((outputFile==NULL)&&(inputFile!=NULL)&&uStringEqual(inputFile,"-")) {
4760e20ee16Smrg	int len;
4770e20ee16Smrg	len= strlen("stdin.eps")+2;
4780e20ee16Smrg	outputFile= uTypedCalloc(len,char);
4790e20ee16Smrg	if (outputFile==NULL) {
4800e20ee16Smrg	    uInternalError("Cannot allocate space for output file name\n");
4810e20ee16Smrg	    uAction("Exiting\n");
4820e20ee16Smrg	    exit(1);
4830e20ee16Smrg	}
4840e20ee16Smrg	if (args.wantEPS)	sprintf(outputFile,"stdin.eps");
4850e20ee16Smrg	else			sprintf(outputFile,"stdin.ps");
4860e20ee16Smrg    }
4870e20ee16Smrg    else if ((outputFile==NULL)&&(inputFile!=NULL)) {
4880e20ee16Smrg	int len;
4890e20ee16Smrg	char *base,*ext;
4900e20ee16Smrg
4910e20ee16Smrg	base= strrchr(inputFile,'/');
4920e20ee16Smrg	if (base==NULL)	base= inputFile;
4930e20ee16Smrg	else		base++;
4940e20ee16Smrg
4950e20ee16Smrg	len= strlen(base)+strlen("eps")+2;
4960e20ee16Smrg	outputFile= uTypedCalloc(len,char);
4970e20ee16Smrg	if (outputFile==NULL) {
4980e20ee16Smrg	    uInternalError("Cannot allocate space for output file name\n");
4990e20ee16Smrg	    uAction("Exiting\n");
5000e20ee16Smrg	    exit(1);
5010e20ee16Smrg	}
5020e20ee16Smrg	ext= strrchr(base,'.');
5030e20ee16Smrg	if (ext==NULL) {
5040e20ee16Smrg	    if (args.wantEPS)	sprintf(outputFile,"%s.eps",base);
5050e20ee16Smrg	    else		sprintf(outputFile,"%s.ps",base);
5060e20ee16Smrg	}
5070e20ee16Smrg	else {
5080e20ee16Smrg	    strcpy(outputFile,base);
5090e20ee16Smrg	    if (args.wantEPS)	strcpy(&outputFile[ext-base+1],"eps");
5100e20ee16Smrg	    else		strcpy(&outputFile[ext-base+1],"ps");
5110e20ee16Smrg	}
5120e20ee16Smrg    }
5130e20ee16Smrg    else if (outputFile==NULL) {
5140e20ee16Smrg	int len;
5150e20ee16Smrg	char *ch,*name,buf[128];
5160e20ee16Smrg	if (inDpyName[0]==':')
5170e20ee16Smrg	     sprintf(name=buf,"server%s",inDpyName);
5180e20ee16Smrg	else name= inDpyName;
5190e20ee16Smrg
5200e20ee16Smrg	len= strlen(name)+strlen("eps")+2;
5210e20ee16Smrg	outputFile= uTypedCalloc(len,char);
5220e20ee16Smrg	if (outputFile==NULL) {
5230e20ee16Smrg	    uInternalError("Cannot allocate space for output file name\n");
5240e20ee16Smrg	    uAction("Exiting\n");
5250e20ee16Smrg	    exit(1);
5260e20ee16Smrg	}
5270e20ee16Smrg	strcpy(outputFile,name);
5280e20ee16Smrg	for (ch=outputFile;(*ch)!='\0';ch++) {
5290e20ee16Smrg	    if 	(*ch==':')	*ch= '-';
5300e20ee16Smrg	    else if (*ch=='.')	*ch= '_';
5310e20ee16Smrg	}
5320e20ee16Smrg	*ch++= '.';
5330e20ee16Smrg	if (args.wantEPS)	strcpy(ch,"eps");
5340e20ee16Smrg	else			strcpy(ch,"ps");
5350e20ee16Smrg    }
5360e20ee16Smrg    else if (strchr(outputFile,':')!=NULL) {
5370e20ee16Smrg	outDpyName= outputFile;
5380e20ee16Smrg	outputFile= NULL;
5390e20ee16Smrg	outputFormat= WANT_X_SERVER;
5400e20ee16Smrg	uInternalError("Output to an X server not implemented yet\n");
5410e20ee16Smrg	return False;
5420e20ee16Smrg    }
5430e20ee16Smrg    return True;
5440e20ee16Smrg}
5450e20ee16Smrg
5460e20ee16Smrgstatic Display *
5470e20ee16SmrgGetDisplay(char *program, char *dpyName)
5480e20ee16Smrg{
5490e20ee16Smrgint	mjr,mnr,error;
5500e20ee16SmrgDisplay	*dpy;
5510e20ee16Smrg
5520e20ee16Smrg    mjr= XkbMajorVersion;
5530e20ee16Smrg    mnr= XkbMinorVersion;
5540e20ee16Smrg    dpy= XkbOpenDisplay(dpyName,NULL,NULL,&mjr,&mnr,&error);
5550e20ee16Smrg    if (dpy==NULL) {
5560e20ee16Smrg	switch (error) {
5570e20ee16Smrg	    case XkbOD_BadLibraryVersion:
5580e20ee16Smrg		uInformation("%s was compiled with XKB version %d.%02d\n",
5590e20ee16Smrg				program,XkbMajorVersion,XkbMinorVersion);
5600e20ee16Smrg		uError("X library supports incompatible version %d.%02d\n",
5610e20ee16Smrg				mjr,mnr);
5620e20ee16Smrg		break;
5630e20ee16Smrg	    case XkbOD_ConnectionRefused:
5640e20ee16Smrg		uError("Cannot open display \"%s\"\n",dpyName);
5650e20ee16Smrg		break;
5660e20ee16Smrg	    case XkbOD_NonXkbServer:
5670e20ee16Smrg		uError("XKB extension not present on %s\n",dpyName);
5680e20ee16Smrg		break;
5690e20ee16Smrg	    case XkbOD_BadServerVersion:
5700e20ee16Smrg		uInformation("%s was compiled with XKB version %d.%02d\n",
5710e20ee16Smrg				program,XkbMajorVersion,XkbMinorVersion);
5720e20ee16Smrg		uError("Server %s uses incompatible version %d.%02d\n",
5730e20ee16Smrg				dpyName,mjr,mnr);
5740e20ee16Smrg		break;
5750e20ee16Smrg	    default:
5760e20ee16Smrg		uInternalError("Unknown error %d from XkbOpenDisplay\n",error);
5770e20ee16Smrg	}
5780e20ee16Smrg    }
5790e20ee16Smrg    else if (synch)
5800e20ee16Smrg	XSynchronize(dpy,True);
5810e20ee16Smrg    return dpy;
5820e20ee16Smrg}
5830e20ee16Smrg
5840e20ee16Smrg/***====================================================================***/
5850e20ee16Smrg
5860e20ee16Smrg#ifdef notyet
5870e20ee16Smrg#define MAX_INCLUDE_OPTS	10
5880e20ee16Smrgstatic char	*includeOpt[MAX_INCLUDE_OPTS];
5890e20ee16Smrgstatic int	numIncludeOpts = 0;
5900e20ee16Smrg#endif
5910e20ee16Smrg
5920e20ee16Smrgint
5930e20ee16Smrgmain(int argc, char *argv[])
5940e20ee16Smrg{
5950e20ee16SmrgFILE 	*	file;
5960e20ee16Smrgint		ok;
5970e20ee16SmrgXkbFileInfo 	result;
5980e20ee16Smrg
5990e20ee16Smrg    uSetEntryFile(NullString);
6000e20ee16Smrg    uSetDebugFile(NullString);
6010e20ee16Smrg    uSetErrorFile(NullString);
6020e20ee16Smrg    if (!parseArgs(argc,argv))
6030e20ee16Smrg	exit(1);
6040e20ee16Smrg#ifdef DEBUG
6050e20ee16Smrg#ifdef sgi
6060e20ee16Smrg    if (debugFlags&0x4)
6070e20ee16Smrg	mallopt(M_DEBUG,1);
6080e20ee16Smrg#endif
6090e20ee16Smrg#endif
6100e20ee16Smrg    file= NULL;
6110e20ee16Smrg    XkbInitAtoms(NULL);
6120e20ee16Smrg/*     XkbInitIncludePath(); */
6130e20ee16Smrg    if (inputFile!=NULL) {
6140e20ee16Smrg	if (uStringEqual(inputFile,"-")) {
6150e20ee16Smrg	    static char *in= "stdin";
6160e20ee16Smrg	    file= stdin;
6170e20ee16Smrg	    inputFile= in;
6180e20ee16Smrg	}
6190e20ee16Smrg	else {
6200e20ee16Smrg	    file= fopen(inputFile,"r");
6210e20ee16Smrg	}
6220e20ee16Smrg    }
6230e20ee16Smrg    else if (inDpyName!=NULL) {
6240e20ee16Smrg	inDpy= GetDisplay(argv[0],inDpyName);
6250e20ee16Smrg	if (!inDpy) {
6260e20ee16Smrg	    uAction("Exiting\n");
6270e20ee16Smrg	    exit(1);
6280e20ee16Smrg	}
6290e20ee16Smrg    }
6300e20ee16Smrg    if (outDpyName!=NULL) {
6310e20ee16Smrg	uInternalError("Output to an X server not implemented yet\n");
6320e20ee16Smrg	outDpy= GetDisplay(argv[0],outDpyName);
6330e20ee16Smrg	if (!outDpy) {
6340e20ee16Smrg	    uAction("Exiting\n");
6350e20ee16Smrg	    exit(1);
6360e20ee16Smrg	}
6370e20ee16Smrg    }
6380e20ee16Smrg    if ((inDpy==NULL) && (outDpy==NULL)) {
6390e20ee16Smrg	int	mjr,mnr;
6400e20ee16Smrg	mjr= XkbMajorVersion;
6410e20ee16Smrg	mnr= XkbMinorVersion;
6420e20ee16Smrg	if (!XkbLibraryVersion(&mjr,&mnr)) {
6430e20ee16Smrg	    uInformation("%s was compiled with XKB version %d.%02d\n",
6440e20ee16Smrg				argv[0],XkbMajorVersion,XkbMinorVersion);
6450e20ee16Smrg	    uError("X library supports incompatible version %d.%02d\n",
6460e20ee16Smrg				mjr,mnr);
6470e20ee16Smrg	    uAction("Exiting\n");
6480e20ee16Smrg	    exit(1);
6490e20ee16Smrg	}
6500e20ee16Smrg    }
6510e20ee16Smrg    ok= True;
6520e20ee16Smrg    if (file) {
6530e20ee16Smrg	unsigned tmp;
6540e20ee16Smrg	bzero((char *)&result,sizeof(result));
6550e20ee16Smrg	if ((result.xkb= XkbAllocKeyboard())==NULL) {
6560e20ee16Smrg	    uFatalError("Cannot allocate keyboard description\n");
6570e20ee16Smrg	    /* NOTREACHED */
6580e20ee16Smrg	}
6590e20ee16Smrg	tmp= XkmReadFile(file,XkmGeometryMask,XkmKeymapLegal,&result);
6600e20ee16Smrg	if ((tmp&XkmGeometryMask)!=0) {
6610e20ee16Smrg	    uError("Couldn't read geometry from XKM file \"%s\"\n",inputFile);
6620e20ee16Smrg	    uAction("Exiting\n");
6630e20ee16Smrg	    ok= False;
6640e20ee16Smrg	}
6650e20ee16Smrg	if ((tmp&XkmKeyNamesMask)!=0)
6660e20ee16Smrg	    args.wantKeycodes= False;
6670e20ee16Smrg	if (args.label==LABEL_AUTO) {
6680e20ee16Smrg	    if (result.defined&XkmSymbolsMask)
6690e20ee16Smrg		 args.label= LABEL_SYMBOLS;
6700e20ee16Smrg	    else if (result.defined&XkmKeyNamesMask)
6710e20ee16Smrg		 args.label= LABEL_KEYCODE;
6720e20ee16Smrg	    else args.label= LABEL_KEYNAME;
6730e20ee16Smrg	}
6740e20ee16Smrg	else if ((args.label==LABEL_KEYCODE)&&((tmp&XkmKeyNamesMask)!=0)) {
6750e20ee16Smrg	    uError("XKM file \"%s\" doesn't have keycodes\n",inputFile);
6760e20ee16Smrg	    uAction("Cannot label keys as requested. Exiting\n");
6770e20ee16Smrg	    ok= False;
6780e20ee16Smrg	}
6790e20ee16Smrg	else if ((args.label==LABEL_SYMBOLS)&&((tmp&XkmSymbolsMask)!=0)) {
6800e20ee16Smrg	    uError("XKM file \"%s\" doesn't have symbols\n",inputFile);
6810e20ee16Smrg	    uAction("Cannot label keys as requested. Exiting\n");
6820e20ee16Smrg	    ok= False;
6830e20ee16Smrg	}
6840e20ee16Smrg    }
6850e20ee16Smrg    else if (inDpy!=NULL) {
6860e20ee16Smrg	bzero((char *)&result,sizeof(result));
6870e20ee16Smrg	result.type= XkmKeymapFile;
6880e20ee16Smrg	result.xkb= XkbGetMap(inDpy,XkbAllMapComponentsMask,XkbUseCoreKbd);
6890e20ee16Smrg	if (result.xkb==NULL)
6900e20ee16Smrg	    uWarning("Cannot load keyboard description\n");
6910e20ee16Smrg	if (XkbGetNames(inDpy,XkbAllNamesMask,result.xkb)!=Success)
6920e20ee16Smrg	    uWarning("Cannot load names\n");
6930e20ee16Smrg	if (XkbGetGeometry(inDpy,result.xkb)!=Success) {
6940e20ee16Smrg	    uFatalError("Cannot load geometry for %s\n",inDpyName);
6950e20ee16Smrg	}
6960e20ee16Smrg#ifdef NOTYET
6970e20ee16Smrg	if (computeDflts)
6980e20ee16Smrg	     ok= (ComputeKbdDefaults(result.xkb)==Success);
6990e20ee16Smrg	else ok= True;
7000e20ee16Smrg#endif
7010e20ee16Smrg	if (args.label==LABEL_AUTO)
7020e20ee16Smrg	    args.label= LABEL_SYMBOLS;
7030e20ee16Smrg    }
7040e20ee16Smrg    else {
7050e20ee16Smrg	fprintf(stderr,"Cannot open \"%s\" to read geometry\n",inputFile);
7060e20ee16Smrg	ok= 0;
7070e20ee16Smrg    }
7080e20ee16Smrg    if (ok) {
7090e20ee16Smrg	FILE *out = NULL;
7100e20ee16Smrg	if (setlocale(LC_ALL,(wantLocale))==NULL) {
7110e20ee16Smrg	    if (wantLocale!=NULL) {
7120e20ee16Smrg		uWarning("Couldn't change to locale %s\n",wantLocale);
7130e20ee16Smrg		uAction("Using \"C\" locale, instead\n");
7140e20ee16Smrg	    }
7150e20ee16Smrg	}
7160e20ee16Smrg	/* need C numerics so decimal point doesn't get screwed up */
7170e20ee16Smrg	setlocale(LC_NUMERIC,"C");
7180e20ee16Smrg	if ((inDpy!=outDpy)&&
7190e20ee16Smrg	    (XkbChangeKbdDisplay(outDpy,&result)!=Success)) {
7200e20ee16Smrg	    uInternalError("Error converting keyboard display from %s to %s\n",
7210e20ee16Smrg	    						inDpyName,outDpyName);
7220e20ee16Smrg	    exit(1);
7230e20ee16Smrg	}
7240e20ee16Smrg	if (outputFile!=NULL) {
7250e20ee16Smrg	    if (uStringEqual(outputFile,"-")) {
7260e20ee16Smrg		static char *of= "stdout";
7270e20ee16Smrg		out= stdout;
7280e20ee16Smrg		outputFile= of;
7290e20ee16Smrg	    }
7300e20ee16Smrg	    else {
7310e20ee16Smrg		out= fopen(outputFile,"w");
7320e20ee16Smrg		if (out==NULL) {
7330e20ee16Smrg		    uError("Cannot open \"%s\" to write keyboard description\n",
7340e20ee16Smrg								outputFile);
7350e20ee16Smrg		     uAction("Exiting\n");
7360e20ee16Smrg		     exit(1);
7370e20ee16Smrg		}
7380e20ee16Smrg	    }
7390e20ee16Smrg	}
7400e20ee16Smrg	switch (outputFormat) {
7410e20ee16Smrg	    case WANT_PS_FILE:
7420e20ee16Smrg		ok= GeometryToPostScript(out,&result,&args);
7430e20ee16Smrg		break;
7440e20ee16Smrg	    case WANT_X_SERVER:
7450e20ee16Smrg		uInternalError("Output to X server not implemented yet\n");
7460e20ee16Smrg		break;
7470e20ee16Smrg	    default:
7480e20ee16Smrg		uInternalError("Unknown output format %d\n",outputFormat);
7490e20ee16Smrg		uAction("No output file created\n");
7500e20ee16Smrg		ok= False;
7510e20ee16Smrg		break;
7520e20ee16Smrg	}
7530e20ee16Smrg	if (!ok) {
7540e20ee16Smrg	    uError("Error creating output file\n");
7550e20ee16Smrg	}
7560e20ee16Smrg    }
7570e20ee16Smrg    if (inDpy)
7580e20ee16Smrg	XCloseDisplay(inDpy);
7590e20ee16Smrg    inDpy= NULL;
7600e20ee16Smrg    if (outDpy)
7610e20ee16Smrg	XCloseDisplay(outDpy);
7620e20ee16Smrg    return (ok==0);
7630e20ee16Smrg}
764