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