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 }
|