(file) Return to setxkbmap.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / setxkbmap

  1 dawes 3.0 /************************************************************
  2            Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
  3           
  4            Permission to use, copy, modify, and distribute this
  5            software and its documentation for any purpose and without
  6            fee is hereby granted, provided that the above copyright
  7            notice appear in all copies and that both that copyright
  8            notice and this permission notice appear in supporting
  9            documentation, and that the name of Silicon Graphics not be 
 10            used in advertising or publicity pertaining to distribution 
 11            of the software without specific prior written permission.
 12            Silicon Graphics makes no representation about the suitability 
 13            of this software for any purpose. It is provided "as is"
 14            without any express or implied warranty.
 15            
 16            SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
 17            SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
 18            AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
 19            GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
 20            DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
 21            DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
 22 dawes 3.0  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 23            THE USE OR PERFORMANCE OF THIS SOFTWARE.
 24           
 25            ********************************************************/
 26 dawes 3.7 /* $XFree86: xc/programs/setxkbmap/setxkbmap.c,v 3.6 2001/08/17 15:39:50 dawes Exp $ */
 27 dawes 3.0 
 28           #include <stdio.h>
 29           #include <stdlib.h>
 30           #include <locale.h>
 31           #include <limits.h>
 32 hohndel 3.2 #include <ctype.h>
 33 dawes   3.0 #include <X11/Xlib.h>
 34 dawes   3.1 #include <X11/Xos.h>
 35 dawes   3.0 #include <X11/XKBlib.h>
 36             #include <X11/extensions/XKBfile.h>
 37             #include <X11/extensions/XKBconfig.h>
 38             #include <X11/extensions/XKBrules.h>
 39             
 40             #ifndef PATH_MAX
 41             #ifdef MAXPATHLEN
 42             #define PATH_MAX MAXPATHLEN
 43             #else
 44             #define PATH_MAX 1024
 45             #endif
 46             #endif
 47             
 48             #ifndef DFLT_XKB_CONFIG_ROOT
 49 dawes   3.4 #define	DFLT_XKB_CONFIG_ROOT "/usr/X11R6/lib/X11/xkb"
 50 dawes   3.0 #endif
 51             #ifndef DFLT_XKB_RULES_FILE
 52 dawes   3.4 #define	DFLT_XKB_RULES_FILE "xfree86"
 53             #endif
 54             #ifndef DFLT_XKB_LAYOUT
 55             #define	DFLT_XKB_LAYOUT "us"
 56             #endif
 57             #ifndef DFLT_XKB_MODEL
 58             #define	DFLT_XKB_MODEL "pc101"
 59 dawes   3.0 #endif
 60             
 61             #define	UNDEFINED	0
 62             #define	FROM_SERVER	1
 63             #define	FROM_RULES	2
 64             #define	FROM_CONFIG	3
 65             #define	FROM_CMD_LINE	4
 66             #define	NUM_SOURCES	5
 67             
 68             #define	RULES_NDX	0
 69             #define	CONFIG_NDX	1
 70             #define	DISPLAY_NDX	2
 71             #define	LOCALE_NDX	3
 72             #define	MODEL_NDX	4
 73             #define	LAYOUT_NDX	5
 74             #define	VARIANT_NDX	6
 75             #define KEYCODES_NDX	7
 76             #define	TYPES_NDX	8
 77             #define	COMPAT_NDX	9
 78             #define	SYMBOLS_NDX	10
 79             #define	GEOMETRY_NDX	11
 80 dawes   3.0 #define	KEYMAP_NDX	12
 81             #define	NUM_STRING_VALS	13
 82             
 83             /***====================================================================***/
 84 dawes   3.7 Bool			print= False;
 85 dawes   3.0 Bool			synch= False;
 86             int			verbose= 5;
 87             
 88             Display *		dpy;
 89             
 90             char *	srcName[NUM_SOURCES] = {
 91             	"undefined", "X server", "rules file", "config file", "command line"
 92             };
 93             
 94             char *	svName[NUM_STRING_VALS]= {
 95             	"rules file", "config file", "X display", "locale",
 96             	"keyboard model", "keyboard layout", "layout variant",
 97             	"keycodes", "types", "compatibility map", "symbols", "geometry",
 98             	"keymap"
 99             };
100             int	svSrc[NUM_STRING_VALS];
101             char *	svValue[NUM_STRING_VALS];
102             
103             XkbConfigFieldsRec	cfgDflts;
104             XkbConfigRtrnRec	cfgResult;
105             
106 dawes   3.0 XkbRF_RulesPtr		rules= NULL;
107             XkbRF_VarDefsRec	rdefs;
108             
109             Bool			clearOptions= False;
110             int			szOptions= 0;
111             int			numOptions= 0;
112             char **			options= NULL;
113             
114             int			szInclPath= 0;
115             int			numInclPath= 0;
116             char **			inclPath= NULL;
117             
118             XkbDescPtr		xkb= NULL;
119             
120             /***====================================================================***/
121             
122             #define	streq(s1,s2)	(strcmp(s1,s2)==0)
123             #define	strpfx(s1,s2)	(strncmp(s1,s2,strlen(s2))==0)
124             
125             #define	MSG(s)		printf(s)
126             #define	MSG1(s,a)	printf(s,a)
127 dawes   3.0 #define	MSG2(s,a,b)	printf(s,a,b)
128             #define	MSG3(s,a,b,c)	printf(s,a,b,c)
129             
130             #define	VMSG(l,s)	if (verbose>(l)) printf(s)
131             #define	VMSG1(l,s,a)	if (verbose>(l)) printf(s,a)
132             #define	VMSG2(l,s,a,b)	if (verbose>(l)) printf(s,a,b)
133             #define	VMSG3(l,s,a,b,c) if (verbose>(l)) printf(s,a,b,c)
134             
135             #define	ERR(s)		fprintf(stderr,s)
136             #define	ERR1(s,a)	fprintf(stderr,s,a)
137             #define	ERR2(s,a,b)	fprintf(stderr,s,a,b)
138             #define	ERR3(s,a,b,c)	fprintf(stderr,s,a,b,c)
139             
140             /***====================================================================***/
141             
142 hohndel 3.2 Bool addToList ( int *sz, int *num, char ***listIn, char *newVal );
143             void usage ( int argc, char ** argv );
144             void dumpNames ( Bool wantRules, Bool wantCNames );
145             void trySetString ( int which, char * newVal, int src );
146             Bool setOptString ( int *arg, int argc, char **argv, int which, int src );
147             int parseArgs ( int argc, char ** argv );
148             Bool getDisplay ( int argc, char ** argv );
149             Bool getServerValues ( void );
150             FILE * findFileInPath ( char * name, char * subdir );
151             Bool addStringToOptions ( char * opt_str, int * sz_opts, int * num_opts, char *** opts );
152             char * stringFromOptions ( char * orig, int numNew, char ** newOpts );
153             Bool applyConfig ( char * name );
154             Bool applyRules ( void );
155             Bool applyComponentNames ( void );
156 dawes   3.7 void printKeymap( void );
157 hohndel 3.2 
158             /***====================================================================***/
159             
160 dawes   3.0 Bool
161             #if NeedFunctionPrototypes
162             addToList(int *sz,int *num,char ***listIn,char *newVal)
163             #else
164             addToList(sz,num,listIn,newVal)
165                 int *	sz;
166                 int *	num;
167                 char ***	listIn;
168                 char *	newVal;
169             #endif
170             {
171             register int i;
172             char **list;
173             
174                 if ((!newVal)||(!newVal[0])) {
175             	*num= 0;
176             	return True;
177                 }
178                 list= *listIn;
179                 for (i=0;i<*num;i++) {
180             	if (streq(list[i],newVal))
181 dawes   3.0 	    return True;
182                 }
183                 if ((list==NULL)||(*sz<1)) {
184             	*num= 0;
185             	*sz= 4;
186             	list= (char **)calloc(*sz,sizeof(char *));
187             	*listIn= list;
188                 }
189                 else if (*num>=*sz) {
190             	*sz*= 2;
191             	list= (char **)realloc(list,(*sz)*sizeof(char *));
192             	*listIn= list;
193                 }
194                 if (!list) {
195             	ERR("Internal Error! Allocation failure in add to list!\n");
196             	ERR("                Exiting.\n");
197             	exit(-1);
198                 }
199                 list[*num]= strdup(newVal);
200                 (*num)= (*num)+1;
201                 return True;
202 dawes   3.0 }
203             
204             /***====================================================================***/
205             
206             void
207             #if NeedFunctionPrototypes
208             usage(int argc,char **argv)
209             #else
210             usage(argc,argv)
211                 int		argc;
212                 char **	argv;
213             #endif
214             {
215                 MSG1("Usage: %s [args] [<layout> [<variant> [<option> ... ]]]\n",argv[0]);
216                 MSG("Where legal args are:\n");
217                 MSG("-?,-help            Print this message\n");
218                 MSG("-compat <name>      Specifies compatibility map component name\n");
219                 MSG("-config <file>      Specifies configuration file to use\n");
220                 MSG("-display <dpy>      Specifies display to use\n");
221                 MSG("-geometry <name>    Specifies geometry component name\n");
222                 MSG("-I[<dir>]           Add <dir> to list of directories to be used\n");
223 dawes   3.0     MSG("-keycodes <name>    Specifies keycodes component name\n");
224                 MSG("-keymap <name>      Specifies name of keymap to load\n");
225                 MSG("-layout <name>      Specifies layout used to choose component names\n");
226                 MSG("-model <name>       Specifies model used to choose component names\n");
227                 MSG("-option <name>      Adds an option used to choose component names\n");
228 dawes   3.7     MSG("-print              Print a complete xkb_keymap description and exit\n");
229 dawes   3.0     MSG("-rules <name>       Name of rules file to use\n");
230                 MSG("-symbols <name>     Specifies symbols component name\n");
231                 MSG("-synch              Synchronize request w/X server\n");
232                 MSG("-types <name>       Specifies types component name\n");
233                 MSG("-v[erbose] [<lvl>]  Sets verbosity (1..10).  Higher values yield\n");
234                 MSG("                    more messages\n");
235                 MSG("-variant <name>     Specifies layout variant used to choose component names\n");
236             }
237             
238             void
239             #if NeedFunctionPrototypes
240             dumpNames(Bool wantRules,Bool wantCNames)
241             #else
242             dumpNames(wantRules,wantCNames)
243                 Bool	wantRules;
244                 Bool	wantCNames;
245             #endif
246             {
247                 if (wantRules) {
248 paulo   3.5 	if (svValue[MODEL_NDX])	 MSG1("model:      %s\n",svValue[MODEL_NDX]);
249             	if (svValue[LAYOUT_NDX])  MSG1("layout:     %s\n",svValue[LAYOUT_NDX]);
250             	if (svValue[VARIANT_NDX]) MSG1("variant:    %s\n",svValue[VARIANT_NDX]);
251             	if (options) {
252             	   char *opt_str=stringFromOptions(NULL, numOptions, options);
253             	   MSG1("options:    %s\n", opt_str);
254             	   free(opt_str);
255             	}
256 dawes   3.0     }
257                 if (wantCNames) {
258             	if (svValue[KEYMAP_NDX])
259             	    MSG1("keymap:     %s\n",svValue[KEYMAP_NDX]);
260             	if (svValue[KEYCODES_NDX])
261             	    MSG1("keycodes:   %s\n",svValue[KEYCODES_NDX]);
262             	if (svValue[TYPES_NDX])
263             	    MSG1("types:      %s\n",svValue[TYPES_NDX]);
264             	if (svValue[COMPAT_NDX])
265             	    MSG1("compat:     %s\n",svValue[COMPAT_NDX]);
266             	if (svValue[SYMBOLS_NDX])
267             	    MSG1("symbols:    %s\n",svValue[SYMBOLS_NDX]);
268             	if (svValue[GEOMETRY_NDX])
269             	    MSG1("geometry:   %s\n",svValue[GEOMETRY_NDX]);
270                 }
271                 return;
272             }
273             
274             /***====================================================================***/
275             
276             void
277 dawes   3.0 #if NeedFunctionPrototypes
278             trySetString(int which,char *newVal,int src)
279             #else
280             trySetString(which,newVal,src)
281                 int		which;
282                 char *	newVal;
283                 int		src;
284             #endif
285             {
286                 if (svValue[which]!=NULL) {
287             	if (svSrc[which]==src) {
288             	    VMSG2(0,"Warning! More than one %s from %s\n",
289             						svName[which],srcName[src]);
290             	    VMSG2(0,"         Using \"%s\", ignoring \"%s\"\n",
291             						svValue[which],newVal);
292             	    return;
293             	}
294             	else if (svSrc[which]>src) {
295             	    VMSG1(5,"Warning! Multiple definitions of %s\n",svName[which]);
296             	    VMSG2(5,"         Using %s, ignoring %s\n",srcName[svSrc[which]],
297             						srcName[src]);
298 dawes   3.0 	    return;
299             	}
300                 }
301                 svSrc[which]= src;
302                 svValue[which]= newVal;
303                 return;
304             }
305             
306             Bool
307             #if NeedFunctionPrototypes
308             setOptString(int *arg,int argc,char **argv,int which,int src)
309             #else
310             setOptString(arg,argc,argv,which,src)
311                 int *	arg;
312                 int 	argc;
313                 char **	argv;
314                 int		what;
315                 int		src;
316             #endif
317             {
318             int	ndx;
319 dawes   3.0 char *	opt;
320             
321                 ndx= *arg;
322                 opt= argv[ndx];
323                 if (ndx>=argc-1) {
324             	VMSG1(0,"No %s specified on the command line\n",svName[which]);
325             	VMSG1(0,"Trailing %s option ignored\n",opt);
326             	return True;
327                 }
328                 ndx++;
329 paulo   3.5     *arg= ndx;
330 dawes   3.0     if (svValue[which]!=NULL) {
331             	if (svSrc[which]==src) {
332             	    VMSG2(0,"More than one %s on %s\n",svName[which],srcName[src]);
333             	    VMSG2(0,"Using \"%s\", ignoring \"%s\"\n",svValue[which],argv[ndx]);
334             	    return True;
335             	}
336             	else if (svSrc[which]>src) {
337             	    VMSG1(5,"Multiple definitions of %s\n",svName[which]);
338             	    VMSG2(5,"Using %s, ignoring %s\n",srcName[svSrc[which]],
339             						srcName[src]);
340             	    return True;
341             	}
342                 }
343                 svSrc[which]= src;
344                 svValue[which]= argv[ndx];
345                 return True;
346             }
347             
348             /***====================================================================***/
349             
350             int
351 dawes   3.0 #if NeedFunctionPrototypes
352             parseArgs(int argc,char **argv)
353             #else
354             parseArgs(argc,argv)
355                 int		argc;
356                 char **	argv;
357             #endif
358             {
359             int 	i;
360             Bool	ok;
361 dawes   3.4 unsigned	present;
362 dawes   3.0 
363                 ok= True;
364                 addToList(&szInclPath,&numInclPath,&inclPath,".");
365                 addToList(&szInclPath,&numInclPath,&inclPath,DFLT_XKB_CONFIG_ROOT);
366                 for (i=1;(i<argc)&&ok;i++) {
367             	if (argv[i][0]!='-') {
368             	    if (!svSrc[LAYOUT_NDX])
369             		 trySetString(LAYOUT_NDX,argv[i],FROM_CMD_LINE);
370             	    else if (!svSrc[VARIANT_NDX])
371             		 trySetString(VARIANT_NDX,argv[i],FROM_CMD_LINE);
372             	    else ok= addToList(&szOptions,&numOptions,&options,argv[i]);
373             	}
374             	else if (streq(argv[i],"-compat"))
375             	    ok= setOptString(&i,argc,argv,COMPAT_NDX,FROM_CMD_LINE);
376             	else if (streq(argv[i],"-config"))
377             	    ok= setOptString(&i,argc,argv,CONFIG_NDX,FROM_CMD_LINE);
378             	else if (streq(argv[i],"-display"))
379             	    ok= setOptString(&i,argc,argv,DISPLAY_NDX,FROM_CMD_LINE);
380             	else if (streq(argv[i],"-geometry"))
381             	    ok= setOptString(&i,argc,argv,GEOMETRY_NDX,FROM_CMD_LINE);
382             	else if (streq(argv[i],"-help")||streq(argv[i],"-?")) {
383 dawes   3.0 	    usage(argc,argv);
384             	    exit(0);
385             	}
386             	else if (strpfx(argv[i],"-I")) 
387             	    ok= addToList(&szInclPath,&numInclPath,&inclPath,&argv[i][2]);
388             	else if (streq(argv[i],"-keycodes"))
389             	    ok= setOptString(&i,argc,argv,KEYCODES_NDX,FROM_CMD_LINE);
390             	else if (streq(argv[i],"-keymap"))
391             	    ok= setOptString(&i,argc,argv,KEYMAP_NDX,FROM_CMD_LINE);
392             	else if (streq(argv[i],"-layout"))
393             	    ok= setOptString(&i,argc,argv,LAYOUT_NDX,FROM_CMD_LINE);
394             	else if (streq(argv[i],"-model"))
395             	    ok= setOptString(&i,argc,argv,MODEL_NDX,FROM_CMD_LINE);
396             	else if (streq(argv[i],"-option")) {
397 dawes   3.6 	    if ((i==argc-1)||(argv[i+1][0]=='\0')||(argv[i+1][0]=='-')) {
398 dawes   3.0 		clearOptions= True;
399             		ok= addToList(&szOptions,&numOptions,&options,"");
400 dawes   3.6                 if (i<argc-1 && argv[i+1][0]=='\0')
401 paulo   3.5                    i++;
402 dawes   3.0 	    }
403             	    else {
404             		ok= addToList(&szOptions,&numOptions,&options,argv[++i]);
405             	    }
406             	}
407 dawes   3.7 	else if (streq(argv[i],"-print"))
408             	    print= True;
409 dawes   3.0 	else if (streq(argv[i],"-rules"))
410             	    ok= setOptString(&i,argc,argv,RULES_NDX,FROM_CMD_LINE);
411             	else if (streq(argv[i],"-symbols"))
412             	    ok= setOptString(&i,argc,argv,SYMBOLS_NDX,FROM_CMD_LINE);
413             	else if (streq(argv[i],"-synch"))
414             	    synch= True;
415             	else if (streq(argv[i],"-types"))
416             	    ok= setOptString(&i,argc,argv,TYPES_NDX,FROM_CMD_LINE);
417             	else if (streq(argv[i],"-verbose")||(streq(argv[i],"-v"))) {
418             	    if ((i<argc-1)&&(isdigit(argv[i+1][0])))
419             	 	 verbose= atoi(argv[++i]);
420             	    else verbose++;
421             	    if (verbose<0) {
422             		ERR1("Illegal verbose level %d.  Reset to 0\n",verbose);
423             		verbose=0;
424             	    }
425             	    else if (verbose>10) {
426             		ERR1("Illegal verbose level %d.  Reset to 10\n",verbose);
427             		verbose= 10;
428             	    }
429             	    VMSG1(7,"Setting verbose level to %d\n",verbose);
430 dawes   3.0 	}
431             	else if (streq(argv[i],"-variant"))
432             	    ok= setOptString(&i,argc,argv,VARIANT_NDX,FROM_CMD_LINE);
433             	else {
434             	    ERR1("Error!   Option \"%s\" not recognized\n",argv[i]);
435             	    ok= False;
436             	}
437                 }
438 dawes   3.4 
439                 present= 0;
440                 if (svValue[TYPES_NDX])	present++;
441                 if (svValue[COMPAT_NDX])	present++;
442                 if (svValue[SYMBOLS_NDX])	present++;
443                 if (svValue[KEYCODES_NDX])	present++;
444                 if (svValue[GEOMETRY_NDX])	present++;
445                 if (svValue[CONFIG_NDX])	present++;
446                 if (svValue[MODEL_NDX])	present++;
447                 if (svValue[LAYOUT_NDX])	present++;
448                 if (svValue[VARIANT_NDX])	present++;
449                 if (svValue[KEYMAP_NDX] && present) {
450             	ERR("No other components can be specified when a keymap is present\n");
451             	return False;
452                 }
453 dawes   3.0     return ok;
454             }
455             
456             Bool
457             #if NeedFunctionPrototypes
458             getDisplay(int argc,char **argv)
459             #else
460             getDisplay(argc,argv)
461                 int		argc;
462                 char **	argv;
463             #endif
464             {
465             int	major,minor,why;
466             
467                 major= XkbMajorVersion;
468                 minor= XkbMinorVersion;
469                 dpy= XkbOpenDisplay(svValue[DISPLAY_NDX],NULL,NULL,&major,&minor,&why);
470                 if (!dpy) {
471             	if (svValue[DISPLAY_NDX]==NULL)	
472             	    svValue[DISPLAY_NDX]= getenv("DISPLAY");
473             	if (svValue[DISPLAY_NDX]==NULL)
474 dawes   3.0 	    svValue[DISPLAY_NDX]= "default display";
475             	switch (why) {
476             	    case XkbOD_BadLibraryVersion:
477             		ERR3("%s was compiled with XKB version %d.%02d\n",argv[0],
478             					XkbMajorVersion,XkbMinorVersion);
479             		ERR2("Xlib supports incompatible version %d.%02d\n",
480             					major,minor);
481             		break;
482             	    case XkbOD_ConnectionRefused:
483                             ERR1("Cannot open display \"%s\"\n",svValue[DISPLAY_NDX]);
484             		break;
485             	    case XkbOD_NonXkbServer:
486             		ERR1("XKB extension not present on %s\n",svValue[DISPLAY_NDX]);
487             		break;
488             	    case XkbOD_BadServerVersion:
489                             ERR3("%s was compiled with XKB version %d.%02d\n",argv[0],
490             				XkbMajorVersion,XkbMinorVersion);
491             		ERR3("Server %s uses incompatible version %d.%02d\n",
492             				svValue[DISPLAY_NDX],major,minor);
493             		break;
494             	    default:
495 dawes   3.0 		ERR1("Unknown error %d from XkbOpenDisplay\n",why);
496             		break;
497             	}
498             	return False;
499                 }
500                 if (synch)
501             	XSynchronize(dpy,True);
502                 return True;
503             }
504             
505             /***====================================================================***/
506             
507             Bool
508             #if NeedFunctionPrototypes
509             getServerValues(void)
510             #else
511             getServerValues()
512             #endif
513             {
514             XkbRF_VarDefsRec 	vd;
515             char *			tmp= NULL;
516 dawes   3.0 
517 dawes   3.4     if (!XkbRF_GetNamesProp(dpy,&tmp,&vd) || !tmp) {
518 dawes   3.0 	VMSG1(3,"Couldn't interpret %s property\n",_XKB_RF_NAMES_PROP_ATOM);
519 dawes   3.4         tmp = DFLT_XKB_RULES_FILE;
520                     vd.model = DFLT_XKB_MODEL;
521                     vd.layout = DFLT_XKB_LAYOUT;
522                     VMSG3(3,"Use defaults: rules - '%s' model - '%s' layout - '%s'\n",
523                             tmp, vd.model, vd.layout);
524 dawes   3.0     }
525                 if (tmp)
526             	trySetString(RULES_NDX,tmp,FROM_SERVER);
527                 if (vd.model)
528             	trySetString(MODEL_NDX,vd.model,FROM_SERVER);
529                 if (vd.layout)
530             	trySetString(LAYOUT_NDX,vd.layout,FROM_SERVER);
531                 if (vd.variant)
532             	trySetString(VARIANT_NDX,vd.variant,FROM_SERVER);
533                 if ((vd.options)&&(!clearOptions)) {
534             	addStringToOptions(vd.options,&szOptions,&numOptions,&options);
535             	XFree(vd.options);
536                 }
537                 return True;
538             }
539             
540             /***====================================================================***/
541             
542             FILE *
543             #if NeedFunctionPrototypes
544             findFileInPath(char *name,char *subdir)
545 dawes   3.0 #else
546             findFileInPath(name,subdir)
547                 char *	name;
548                 char *	subdir;
549             #endif
550             {
551             register int	i;
552             char		buf[PATH_MAX];
553             FILE *		fp;
554             
555                 if (name[0]=='/') {
556             	fp= fopen(name,"r");
557             	if ((verbose>7)||((!fp)&&(verbose>0)))
558             	    MSG2("%s file %s\n",(fp?"Found":"Didn't find"),name);
559             	return fp;
560                 }
561                 for (i=0;(i<numInclPath);i++) {
562             	if ((strlen(inclPath[i])+strlen(subdir)+strlen(name)+2)>PATH_MAX) {
563             	    VMSG3(0,"Path too long (%s/%s%s). Ignored.\n",inclPath[i],subdir,
564             									name);
565             	    continue;
566 dawes   3.0 	}
567             	sprintf(buf,"%s/%s%s",inclPath[i],subdir,name);
568             	fp= fopen(name,"r");
569             	if ((verbose>7)||((!fp)&&(verbose>5)))
570             	    MSG2("%s file %s\n",(fp?"Found":"Didn't find"),buf);
571             	if (fp!=NULL)
572             	    return fp;
573                 }
574                 return NULL;
575             }
576             
577             /***====================================================================***/
578             
579             Bool
580             #if NeedFunctionPrototypes
581             addStringToOptions(char *opt_str,int *sz_opts,int *num_opts,char ***opts)
582             #else
583             addStringToOptions(opt_str,sz_opts,num_opts,opts)
584                 char *	opt_str;
585                 int *	sz_opts;
586                 int *	num_opts;
587 dawes   3.0     char ***	opts;
588             #endif
589             {
590             char 	*tmp,*str,*next;
591             Bool	ok= True;
592             
593                 if ((str= malloc(strlen(opt_str)+1))!=NULL)
594             	 strcpy(str,opt_str);
595                 else return False;
596                 for (tmp= str,next=NULL;(tmp && *tmp!='\0')&&ok;tmp=next) {
597             	next= strchr(str,',');
598             	if (next) {
599             	    *next= '\0';
600             	    next++;
601             	}
602             	ok= addToList(sz_opts,num_opts,opts,tmp)&&ok;
603                 }
604                 free(str);
605                 return ok;
606             }
607             
608 dawes   3.0 /***====================================================================***/
609             
610             char *
611             #if NeedFunctionPrototypes
612             stringFromOptions(char *orig,int numNew,char **newOpts)
613             #else
614             stringFromOptions(orig,numNew,newOpts)
615                 char *	orig;
616                 int		numNew;
617                 char **	newOpts;
618             #endif
619             {
620             int	len,i,nOut;
621             
622                 if (orig)	len= strlen(orig)+1;
623                 else	len= 0;
624                 for (i=0;i<numNew;i++) {
625             	if (newOpts[i])
626             	    len+= strlen(newOpts[i])+1;
627                 }
628                 if (len<1)
629 dawes   3.0 	return NULL;
630                 if (orig) {
631             	orig= (char *)realloc(orig,len);
632             	nOut= 1;
633                 }
634                 else {
635             	orig= (char *)calloc(len,1);
636             	nOut= 0;
637                 }
638                 for (i=0;i<numNew;i++) {
639             	if (!newOpts[i])
640             	    continue;
641             	if (nOut>0) {
642             	     strcat(orig,",");
643             	     strcat(orig,newOpts[i]);
644             	}
645             	else strcpy(orig,newOpts[i]);
646             	nOut++;
647                 }
648                 return orig;
649             }
650 dawes   3.0 
651             /***====================================================================***/
652             
653             Bool
654             #if NeedFunctionPrototypes
655             applyConfig(char *name)
656             #else
657             applyConfig(name)
658                 char *	name;
659             #endif
660             {
661             FILE *	fp;
662             Bool	ok;
663                 
664                 if ((fp=findFileInPath(name,""))==NULL)
665             	return False;
666                 ok= XkbCFParse(fp,XkbCFDflts,NULL,&cfgResult);
667                 fclose(fp);
668                 if (!ok) {
669 hohndel 3.2 	ERR1("Couldn't find configuration file \"%s\"\n", name);
670 dawes   3.0 	return False;
671                 }
672                 if (cfgResult.rules_file) {
673             	trySetString(RULES_NDX,cfgResult.rules_file,FROM_CONFIG);
674             	cfgResult.rules_file= NULL;
675                 }
676                 if (cfgResult.model) {
677             	trySetString(MODEL_NDX,cfgResult.model,FROM_CONFIG);
678             	cfgResult.model= NULL;
679                 }
680                 if (cfgResult.layout) {
681             	trySetString(LAYOUT_NDX,cfgResult.layout,FROM_CONFIG);
682             	cfgResult.layout= NULL;
683                 }
684                 if (cfgResult.variant) {
685             	trySetString(VARIANT_NDX,cfgResult.variant,FROM_CONFIG);
686             	cfgResult.variant= NULL;
687                 }
688                 if (cfgResult.options) {
689             	addStringToOptions(cfgResult.options,&szOptions,&numOptions,&options);
690             	cfgResult.options= NULL;
691 dawes   3.0     }
692                 if (cfgResult.keymap) {
693             	trySetString(KEYMAP_NDX,cfgResult.keymap,FROM_CONFIG);
694             	cfgResult.keymap= NULL;
695                 }
696                 if (cfgResult.keycodes) {
697             	trySetString(KEYCODES_NDX,cfgResult.keycodes,FROM_CONFIG);
698             	cfgResult.keycodes= NULL;
699                 }
700                 if (cfgResult.geometry) {
701             	trySetString(GEOMETRY_NDX,cfgResult.geometry,FROM_CONFIG);
702             	cfgResult.geometry= NULL;
703                 }
704                 if (cfgResult.symbols) {
705             	trySetString(SYMBOLS_NDX,cfgResult.symbols,FROM_CONFIG);
706             	cfgResult.symbols= NULL;
707                 }
708                 if (cfgResult.types) {
709             	trySetString(TYPES_NDX,cfgResult.types,FROM_CONFIG);
710             	cfgResult.types= NULL;
711                 }
712 dawes   3.0     if (cfgResult.compat) {
713             	trySetString(COMPAT_NDX,cfgResult.compat,FROM_CONFIG);
714             	cfgResult.compat= NULL;
715                 }
716                 if (verbose>5) {
717             	MSG("After config file:\n");
718             	dumpNames(True,True);
719                 }
720                 return True;
721             }
722             
723             Bool
724             #if NeedFunctionPrototypes
725             applyRules(void)
726             #else
727             applyRules()
728             #endif
729             {
730             int	i;
731             char *	rfName;
732             
733 dawes   3.0     if (svSrc[MODEL_NDX]||svSrc[LAYOUT_NDX]||svSrc[VARIANT_NDX]||options) {
734             	char 			buf[PATH_MAX];
735             	XkbComponentNamesRec	rnames;
736             
737 paulo   3.5         if(svSrc[VARIANT_NDX] < svSrc[LAYOUT_NDX])
738                         svValue[VARIANT_NDX] = NULL;
739 dawes   3.0 
740             	rdefs.model= svValue[MODEL_NDX];
741             	rdefs.layout= svValue[LAYOUT_NDX];
742             	rdefs.variant= svValue[VARIANT_NDX];
743             	if (options)
744             	    rdefs.options=stringFromOptions(rdefs.options,numOptions,options);
745             
746             	if (svSrc[RULES_NDX])
747             	     rfName= svValue[RULES_NDX];
748             	else rfName= DFLT_XKB_RULES_FILE;
749             
750             	if (rfName[0]=='/') {
751             	    rules= XkbRF_Load(rfName,svValue[LOCALE_NDX],True,True);
752             	}
753             	else {
754             	    for (i=0;(i<numInclPath)&&(!rules);i++) {
755             		if ((strlen(inclPath[i])+strlen(rfName)+8)>PATH_MAX) {
756             		    VMSG2(0,"Path too long (%s/rules/%s). Ignored.\n",
757             						inclPath[i],rfName);
758             		    continue;
759             		}
760 dawes   3.0 		sprintf(buf,"%s/rules/%s",inclPath[i],svValue[RULES_NDX]);
761             		rules= XkbRF_Load(buf,svValue[LOCALE_NDX],True,True);
762             	    }
763             	}
764             	if (!rules) {
765             	    ERR1("Couldn't find rules file (%s) \n",svValue[RULES_NDX]);
766             	    return False;
767             	}
768             	XkbRF_GetComponents(rules,&rdefs,&rnames);
769             	if (rnames.keycodes) {
770             	    trySetString(KEYCODES_NDX,rnames.keycodes,FROM_RULES);
771             	    rnames.keycodes= NULL;
772             	}
773             	if (rnames.symbols) {
774             	    trySetString(SYMBOLS_NDX,rnames.symbols,FROM_RULES);
775             	    rnames.symbols= NULL;
776             	}
777             	if (rnames.types) {
778             	    trySetString(TYPES_NDX,rnames.types,FROM_RULES);
779             	    rnames.types= NULL;
780             	}
781 dawes   3.0 	if (rnames.compat) {
782             	    trySetString(COMPAT_NDX,rnames.compat,FROM_RULES);
783             	    rnames.compat= NULL;
784             	}
785             	if (rnames.geometry) {
786             	    trySetString(GEOMETRY_NDX,rnames.geometry,FROM_RULES);
787             	    rnames.geometry= NULL;
788             	}
789             	if (rnames.keymap) {
790             	    trySetString(KEYMAP_NDX,rnames.keymap,FROM_RULES);
791             	    rnames.keymap= NULL;
792             	}
793             	if (verbose>6) {
794             	    MSG1("Applied rules from %s:\n",svValue[RULES_NDX]);
795 paulo   3.5 	    dumpNames(True,False);
796 dawes   3.0 	}
797                 }
798                 else if (verbose>6) {
799             	MSG("No rules variables specified.  Rules file ignored\n");
800                 }
801                 return True;
802             }
803             
804 dawes   3.4 /* Primitive sanity check - filter out 'map names' (inside parenthesis) */
805             /* that can confuse xkbcomp parser */
806             Bool
807             #if NeedFunctionPrototypes
808             checkName(char *name, char* string)
809             #else
810             checkName()
811                 char *name;
812                 char *string;
813             #endif
814             {
815                char *i = name, *opar = NULL;
816                Bool ret = True;
817             
818                if(!name)
819                   return True;
820             
821                while (*i){
822                   if (opar == NULL) {
823                      if (*i == '(')
824                      opar = i;
825 dawes   3.4       } else {
826                      if ((*i == '(') || (*i == '|') || (*i == '+')) {
827                          ret = False;
828                          break;
829                      }
830                      if (*i == ')')
831                          opar = NULL;
832                   }
833                   i++;
834                }
835                if (opar)
836                   ret = False;
837                if (!ret) {
838                   char c;
839                   int n = 1;
840                   for(i = opar+1; *i && n; i++) {
841                      if (*i == '(') n++;
842                      if (*i == ')') n--;
843                   }
844                   if (*i) i++;
845                   c = *i;
846 dawes   3.4       *i = '\0';
847                   ERR1("Illegal map name '%s' ", opar);
848                   *i = c;
849                   ERR2("in %s name '%s'\n", string, name);
850                }
851                return ret;
852             }
853 dawes   3.0 
854 dawes   3.7 void
855             #if NeedFunctionPrototypes
856             printKeymap(void)
857             #else
858             printKeymap()
859             #endif
860             {
861                 MSG("xkb_keymap {\n");
862                 if (svValue[KEYCODES_NDX])
863             	MSG1("\txkb_keycodes  { include \"%s\"\t};\n",svValue[KEYCODES_NDX]);
864                 if (svValue[TYPES_NDX])
865             	MSG1("\txkb_types     { include \"%s\"\t};\n",svValue[TYPES_NDX]);
866                 if (svValue[COMPAT_NDX])
867             	MSG1("\txkb_compat    { include \"%s\"\t};\n",svValue[COMPAT_NDX]);
868                 if (svValue[SYMBOLS_NDX])
869             	MSG1("\txkb_symbols   { include \"%s\"\t};\n",svValue[SYMBOLS_NDX]);
870                 if (svValue[GEOMETRY_NDX])
871             	MSG1("\txkb_geometry  { include \"%s\"\t};\n",svValue[GEOMETRY_NDX]);
872                 MSG("};\n");
873             }
874             
875 dawes   3.0 Bool
876             #if NeedFunctionPrototypes
877             applyComponentNames(void)
878             #else
879             applyComponentNames()
880             #endif
881             {
882 dawes   3.4     if(!checkName(svValue[TYPES_NDX],    "types"))
883             	return False;
884                 if(!checkName(svValue[COMPAT_NDX],   "compat"))
885             	return False;
886                 if(!checkName(svValue[SYMBOLS_NDX],  "symbols"))
887             	return False;
888                 if(!checkName(svValue[KEYCODES_NDX], "keycodes"))
889             	return False;
890                 if(!checkName(svValue[GEOMETRY_NDX], "geometry"))
891 dawes   3.0 	return False;
892 dawes   3.4     if(!checkName(svValue[KEYMAP_NDX],   "keymap"))
893 dawes   3.0 	return False;
894 dawes   3.4 
895 dawes   3.0     if (verbose>5) {
896             	MSG("Trying to build keymap using the following components:\n");
897 paulo   3.5 	dumpNames(False,True);
898 dawes   3.0     }
899 dawes   3.7     if (dpy && !print) {
900 dawes   3.0 	XkbComponentNamesRec	cmdNames;
901             	cmdNames.types= svValue[TYPES_NDX];
902             	cmdNames.compat= svValue[COMPAT_NDX];
903             	cmdNames.symbols= svValue[SYMBOLS_NDX];
904             	cmdNames.keycodes= svValue[KEYCODES_NDX];
905             	cmdNames.geometry= svValue[GEOMETRY_NDX];
906             	cmdNames.keymap= svValue[KEYMAP_NDX];
907             	xkb= XkbGetKeyboardByName(dpy,XkbUseCoreKbd,&cmdNames,
908             			XkbGBN_AllComponentsMask, 
909             			XkbGBN_AllComponentsMask&(~XkbGBN_GeometryMask),
910             			True);
911             	if (!xkb) {
912             	    ERR("Error loading new keyboard description\n");
913             	    return False;
914             	}
915             	if (svValue[RULES_NDX] && (rdefs.model || rdefs.layout)) {
916             	    if (!XkbRF_SetNamesProp(dpy,svValue[RULES_NDX],&rdefs)) {
917             		VMSG(0,"Error updating the XKB names property\n");
918             	    }
919             	}
920 dawes   3.7     }
921                 if (print) {
922                     printKeymap();
923 dawes   3.0     }
924                 return True;
925             }
926             
927             
928             int
929             #if NeedFunctionPrototypes
930             main(int argc,char **argv)
931             #else
932             main(argc,argv)
933                 int		argc;
934                 char **	argv;
935             #endif
936             {
937                 if ((!parseArgs(argc,argv))||(!getDisplay(argc,argv)))
938             	exit(-1);
939                 svValue[LOCALE_NDX]= setlocale(LC_ALL,svValue[LOCALE_NDX]);
940                 svSrc[LOCALE_NDX]= FROM_SERVER;
941                 VMSG1(7,"locale is %s\n",svValue[LOCALE_NDX]);
942 dawes   3.4     if (dpy)
943                     getServerValues();
944 dawes   3.0     if (svValue[CONFIG_NDX] && (!applyConfig(svValue[CONFIG_NDX])))
945             	exit(-3);
946                 if (!applyRules())
947             	exit(-4);
948                 if (!applyComponentNames())
949             	exit(-5);
950                 if (dpy)
951             	XCloseDisplay(dpy);
952 hohndel 3.2     exit(0);
953 dawes   3.0 }

Powered by
ViewCVS 0.9.2