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 tsi 3.10 /* $XFree86: xc/programs/setxkbmap/setxkbmap.c,v 3.9tsi 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 addToList(int *sz,int *num,char ***listIn,char *newVal)
162 {
163 register int i;
164 char **list;
165
166 if ((!newVal)||(!newVal[0])) {
167 *num= 0;
168 return True;
169 }
170 list= *listIn;
171 for (i=0;i<*num;i++) {
172 if (streq(list[i],newVal))
173 return True;
174 }
175 if ((list==NULL)||(*sz<1)) {
176 *num= 0;
177 *sz= 4;
178 list= (char **)calloc(*sz,sizeof(char *));
179 *listIn= list;
180 }
181 dawes 3.0 else if (*num>=*sz) {
182 *sz*= 2;
183 list= (char **)realloc(list,(*sz)*sizeof(char *));
184 *listIn= list;
185 }
186 if (!list) {
187 ERR("Internal Error! Allocation failure in add to list!\n");
188 ERR(" Exiting.\n");
189 exit(-1);
190 }
191 list[*num]= strdup(newVal);
192 (*num)= (*num)+1;
193 return True;
194 }
195
196 /***====================================================================***/
197
198 void
199 usage(int argc,char **argv)
200 {
201 MSG1("Usage: %s [args] [<layout> [<variant> [<option> ... ]]]\n",argv[0]);
202 dawes 3.0 MSG("Where legal args are:\n");
203 MSG("-?,-help Print this message\n");
204 MSG("-compat <name> Specifies compatibility map component name\n");
205 MSG("-config <file> Specifies configuration file to use\n");
206 MSG("-display <dpy> Specifies display to use\n");
207 MSG("-geometry <name> Specifies geometry component name\n");
208 MSG("-I[<dir>] Add <dir> to list of directories to be used\n");
209 MSG("-keycodes <name> Specifies keycodes component name\n");
210 MSG("-keymap <name> Specifies name of keymap to load\n");
211 MSG("-layout <name> Specifies layout used to choose component names\n");
212 MSG("-model <name> Specifies model used to choose component names\n");
213 MSG("-option <name> Adds an option used to choose component names\n");
|
214 dawes 3.7 MSG("-print Print a complete xkb_keymap description and exit\n");
|
215 dawes 3.0 MSG("-rules <name> Name of rules file to use\n");
216 MSG("-symbols <name> Specifies symbols component name\n");
217 MSG("-synch Synchronize request w/X server\n");
218 MSG("-types <name> Specifies types component name\n");
219 MSG("-v[erbose] [<lvl>] Sets verbosity (1..10). Higher values yield\n");
220 MSG(" more messages\n");
221 MSG("-variant <name> Specifies layout variant used to choose component names\n");
222 }
223
224 void
225 dumpNames(Bool wantRules,Bool wantCNames)
226 {
227 if (wantRules) {
|
228 paulo 3.5 if (svValue[MODEL_NDX]) MSG1("model: %s\n",svValue[MODEL_NDX]);
229 if (svValue[LAYOUT_NDX]) MSG1("layout: %s\n",svValue[LAYOUT_NDX]);
230 if (svValue[VARIANT_NDX]) MSG1("variant: %s\n",svValue[VARIANT_NDX]);
231 if (options) {
232 char *opt_str=stringFromOptions(NULL, numOptions, options);
233 MSG1("options: %s\n", opt_str);
234 free(opt_str);
235 }
|
236 dawes 3.0 }
237 if (wantCNames) {
238 if (svValue[KEYMAP_NDX])
239 MSG1("keymap: %s\n",svValue[KEYMAP_NDX]);
240 if (svValue[KEYCODES_NDX])
241 MSG1("keycodes: %s\n",svValue[KEYCODES_NDX]);
242 if (svValue[TYPES_NDX])
243 MSG1("types: %s\n",svValue[TYPES_NDX]);
244 if (svValue[COMPAT_NDX])
245 MSG1("compat: %s\n",svValue[COMPAT_NDX]);
246 if (svValue[SYMBOLS_NDX])
247 MSG1("symbols: %s\n",svValue[SYMBOLS_NDX]);
248 if (svValue[GEOMETRY_NDX])
249 MSG1("geometry: %s\n",svValue[GEOMETRY_NDX]);
250 }
251 return;
252 }
253
254 /***====================================================================***/
255
256 void
257 dawes 3.0 trySetString(int which,char *newVal,int src)
258 {
259 if (svValue[which]!=NULL) {
260 if (svSrc[which]==src) {
261 VMSG2(0,"Warning! More than one %s from %s\n",
262 svName[which],srcName[src]);
263 VMSG2(0," Using \"%s\", ignoring \"%s\"\n",
264 svValue[which],newVal);
265 return;
266 }
267 else if (svSrc[which]>src) {
268 VMSG1(5,"Warning! Multiple definitions of %s\n",svName[which]);
269 VMSG2(5," Using %s, ignoring %s\n",srcName[svSrc[which]],
270 srcName[src]);
271 return;
272 }
273 }
274 svSrc[which]= src;
275 svValue[which]= newVal;
276 return;
277 }
278 dawes 3.0
279 Bool
280 setOptString(int *arg,int argc,char **argv,int which,int src)
281 {
282 int ndx;
283 char * opt;
284
285 ndx= *arg;
286 opt= argv[ndx];
287 if (ndx>=argc-1) {
288 VMSG1(0,"No %s specified on the command line\n",svName[which]);
289 VMSG1(0,"Trailing %s option ignored\n",opt);
290 return True;
291 }
292 ndx++;
|
293 paulo 3.5 *arg= ndx;
|
294 dawes 3.0 if (svValue[which]!=NULL) {
295 if (svSrc[which]==src) {
296 VMSG2(0,"More than one %s on %s\n",svName[which],srcName[src]);
297 VMSG2(0,"Using \"%s\", ignoring \"%s\"\n",svValue[which],argv[ndx]);
298 return True;
299 }
300 else if (svSrc[which]>src) {
301 VMSG1(5,"Multiple definitions of %s\n",svName[which]);
302 VMSG2(5,"Using %s, ignoring %s\n",srcName[svSrc[which]],
303 srcName[src]);
304 return True;
305 }
306 }
307 svSrc[which]= src;
308 svValue[which]= argv[ndx];
309 return True;
310 }
311
312 /***====================================================================***/
313
314 int
315 dawes 3.0 parseArgs(int argc,char **argv)
316 {
317 int i;
318 Bool ok;
|
319 dawes 3.4 unsigned present;
|
320 dawes 3.0
321 ok= True;
322 addToList(&szInclPath,&numInclPath,&inclPath,".");
323 addToList(&szInclPath,&numInclPath,&inclPath,DFLT_XKB_CONFIG_ROOT);
324 for (i=1;(i<argc)&&ok;i++) {
325 if (argv[i][0]!='-') {
326 if (!svSrc[LAYOUT_NDX])
327 trySetString(LAYOUT_NDX,argv[i],FROM_CMD_LINE);
328 else if (!svSrc[VARIANT_NDX])
329 trySetString(VARIANT_NDX,argv[i],FROM_CMD_LINE);
330 else ok= addToList(&szOptions,&numOptions,&options,argv[i]);
331 }
332 else if (streq(argv[i],"-compat"))
333 ok= setOptString(&i,argc,argv,COMPAT_NDX,FROM_CMD_LINE);
334 else if (streq(argv[i],"-config"))
335 ok= setOptString(&i,argc,argv,CONFIG_NDX,FROM_CMD_LINE);
336 else if (streq(argv[i],"-display"))
337 ok= setOptString(&i,argc,argv,DISPLAY_NDX,FROM_CMD_LINE);
338 else if (streq(argv[i],"-geometry"))
339 ok= setOptString(&i,argc,argv,GEOMETRY_NDX,FROM_CMD_LINE);
340 else if (streq(argv[i],"-help")||streq(argv[i],"-?")) {
341 dawes 3.0 usage(argc,argv);
342 exit(0);
343 }
344 else if (strpfx(argv[i],"-I"))
345 ok= addToList(&szInclPath,&numInclPath,&inclPath,&argv[i][2]);
346 else if (streq(argv[i],"-keycodes"))
347 ok= setOptString(&i,argc,argv,KEYCODES_NDX,FROM_CMD_LINE);
348 else if (streq(argv[i],"-keymap"))
349 ok= setOptString(&i,argc,argv,KEYMAP_NDX,FROM_CMD_LINE);
350 else if (streq(argv[i],"-layout"))
351 ok= setOptString(&i,argc,argv,LAYOUT_NDX,FROM_CMD_LINE);
352 else if (streq(argv[i],"-model"))
353 ok= setOptString(&i,argc,argv,MODEL_NDX,FROM_CMD_LINE);
354 else if (streq(argv[i],"-option")) {
|
355 dawes 3.6 if ((i==argc-1)||(argv[i+1][0]=='\0')||(argv[i+1][0]=='-')) {
|
356 dawes 3.0 clearOptions= True;
357 ok= addToList(&szOptions,&numOptions,&options,"");
|
358 dawes 3.6 if (i<argc-1 && argv[i+1][0]=='\0')
|
359 paulo 3.5 i++;
|
360 dawes 3.0 }
361 else {
362 ok= addToList(&szOptions,&numOptions,&options,argv[++i]);
363 }
364 }
|
365 dawes 3.7 else if (streq(argv[i],"-print"))
366 print= True;
|
367 dawes 3.0 else if (streq(argv[i],"-rules"))
368 ok= setOptString(&i,argc,argv,RULES_NDX,FROM_CMD_LINE);
369 else if (streq(argv[i],"-symbols"))
370 ok= setOptString(&i,argc,argv,SYMBOLS_NDX,FROM_CMD_LINE);
371 else if (streq(argv[i],"-synch"))
372 synch= True;
373 else if (streq(argv[i],"-types"))
374 ok= setOptString(&i,argc,argv,TYPES_NDX,FROM_CMD_LINE);
375 else if (streq(argv[i],"-verbose")||(streq(argv[i],"-v"))) {
376 if ((i<argc-1)&&(isdigit(argv[i+1][0])))
377 verbose= atoi(argv[++i]);
378 else verbose++;
379 if (verbose<0) {
380 ERR1("Illegal verbose level %d. Reset to 0\n",verbose);
381 verbose=0;
382 }
383 else if (verbose>10) {
384 ERR1("Illegal verbose level %d. Reset to 10\n",verbose);
385 verbose= 10;
386 }
387 VMSG1(7,"Setting verbose level to %d\n",verbose);
388 dawes 3.0 }
389 else if (streq(argv[i],"-variant"))
390 ok= setOptString(&i,argc,argv,VARIANT_NDX,FROM_CMD_LINE);
391 else {
392 ERR1("Error! Option \"%s\" not recognized\n",argv[i]);
393 ok= False;
394 }
395 }
|
396 dawes 3.4
397 present= 0;
398 if (svValue[TYPES_NDX]) present++;
399 if (svValue[COMPAT_NDX]) present++;
400 if (svValue[SYMBOLS_NDX]) present++;
401 if (svValue[KEYCODES_NDX]) present++;
402 if (svValue[GEOMETRY_NDX]) present++;
403 if (svValue[CONFIG_NDX]) present++;
404 if (svValue[MODEL_NDX]) present++;
405 if (svValue[LAYOUT_NDX]) present++;
406 if (svValue[VARIANT_NDX]) present++;
407 if (svValue[KEYMAP_NDX] && present) {
408 ERR("No other components can be specified when a keymap is present\n");
409 return False;
410 }
|
411 dawes 3.0 return ok;
412 }
413
414 Bool
415 getDisplay(int argc,char **argv)
416 {
417 int major,minor,why;
418
419 major= XkbMajorVersion;
420 minor= XkbMinorVersion;
421 dpy= XkbOpenDisplay(svValue[DISPLAY_NDX],NULL,NULL,&major,&minor,&why);
422 if (!dpy) {
423 if (svValue[DISPLAY_NDX]==NULL)
424 svValue[DISPLAY_NDX]= getenv("DISPLAY");
425 if (svValue[DISPLAY_NDX]==NULL)
426 svValue[DISPLAY_NDX]= "default display";
427 switch (why) {
428 case XkbOD_BadLibraryVersion:
429 ERR3("%s was compiled with XKB version %d.%02d\n",argv[0],
430 XkbMajorVersion,XkbMinorVersion);
431 ERR2("Xlib supports incompatible version %d.%02d\n",
432 dawes 3.0 major,minor);
433 break;
434 case XkbOD_ConnectionRefused:
435 ERR1("Cannot open display \"%s\"\n",svValue[DISPLAY_NDX]);
436 break;
437 case XkbOD_NonXkbServer:
438 ERR1("XKB extension not present on %s\n",svValue[DISPLAY_NDX]);
439 break;
440 case XkbOD_BadServerVersion:
441 ERR3("%s was compiled with XKB version %d.%02d\n",argv[0],
442 XkbMajorVersion,XkbMinorVersion);
443 ERR3("Server %s uses incompatible version %d.%02d\n",
444 svValue[DISPLAY_NDX],major,minor);
445 break;
446 default:
447 ERR1("Unknown error %d from XkbOpenDisplay\n",why);
448 break;
449 }
450 return False;
451 }
452 if (synch)
453 dawes 3.0 XSynchronize(dpy,True);
454 return True;
455 }
456
457 /***====================================================================***/
458
459 Bool
460 getServerValues(void)
461 {
462 XkbRF_VarDefsRec vd;
463 char * tmp= NULL;
464
|
465 dawes 3.4 if (!XkbRF_GetNamesProp(dpy,&tmp,&vd) || !tmp) {
|
466 dawes 3.0 VMSG1(3,"Couldn't interpret %s property\n",_XKB_RF_NAMES_PROP_ATOM);
|
467 dawes 3.4 tmp = DFLT_XKB_RULES_FILE;
468 vd.model = DFLT_XKB_MODEL;
469 vd.layout = DFLT_XKB_LAYOUT;
|
470 tsi 3.10 vd.variant = NULL;
471 vd.options = NULL;
|
472 dawes 3.4 VMSG3(3,"Use defaults: rules - '%s' model - '%s' layout - '%s'\n",
473 tmp, vd.model, vd.layout);
|
474 dawes 3.0 }
475 if (tmp)
476 trySetString(RULES_NDX,tmp,FROM_SERVER);
477 if (vd.model)
478 trySetString(MODEL_NDX,vd.model,FROM_SERVER);
479 if (vd.layout)
480 trySetString(LAYOUT_NDX,vd.layout,FROM_SERVER);
481 if (vd.variant)
482 trySetString(VARIANT_NDX,vd.variant,FROM_SERVER);
483 if ((vd.options)&&(!clearOptions)) {
484 addStringToOptions(vd.options,&szOptions,&numOptions,&options);
485 XFree(vd.options);
486 }
487 return True;
488 }
489
490 /***====================================================================***/
491
492 FILE *
493 findFileInPath(char *name,char *subdir)
494 {
495 dawes 3.0 register int i;
496 char buf[PATH_MAX];
497 FILE * fp;
498
499 if (name[0]=='/') {
500 fp= fopen(name,"r");
501 if ((verbose>7)||((!fp)&&(verbose>0)))
502 MSG2("%s file %s\n",(fp?"Found":"Didn't find"),name);
503 return fp;
504 }
505 for (i=0;(i<numInclPath);i++) {
506 if ((strlen(inclPath[i])+strlen(subdir)+strlen(name)+2)>PATH_MAX) {
507 VMSG3(0,"Path too long (%s/%s%s). Ignored.\n",inclPath[i],subdir,
508 name);
509 continue;
510 }
511 sprintf(buf,"%s/%s%s",inclPath[i],subdir,name);
512 fp= fopen(name,"r");
513 if ((verbose>7)||((!fp)&&(verbose>5)))
514 MSG2("%s file %s\n",(fp?"Found":"Didn't find"),buf);
515 if (fp!=NULL)
516 dawes 3.0 return fp;
517 }
518 return NULL;
519 }
520
521 /***====================================================================***/
522
523 Bool
524 addStringToOptions(char *opt_str,int *sz_opts,int *num_opts,char ***opts)
525 {
526 char *tmp,*str,*next;
527 Bool ok= True;
528
529 if ((str= malloc(strlen(opt_str)+1))!=NULL)
530 strcpy(str,opt_str);
531 else return False;
532 for (tmp= str,next=NULL;(tmp && *tmp!='\0')&&ok;tmp=next) {
533 next= strchr(str,',');
534 if (next) {
535 *next= '\0';
536 next++;
537 dawes 3.0 }
538 ok= addToList(sz_opts,num_opts,opts,tmp)&&ok;
539 }
540 free(str);
541 return ok;
542 }
543
544 /***====================================================================***/
545
546 char *
547 stringFromOptions(char *orig,int numNew,char **newOpts)
548 {
549 int len,i,nOut;
550
551 if (orig) len= strlen(orig)+1;
552 else len= 0;
553 for (i=0;i<numNew;i++) {
554 if (newOpts[i])
555 len+= strlen(newOpts[i])+1;
556 }
557 if (len<1)
558 dawes 3.0 return NULL;
559 if (orig) {
560 orig= (char *)realloc(orig,len);
561 nOut= 1;
562 }
563 else {
564 orig= (char *)calloc(len,1);
565 nOut= 0;
566 }
567 for (i=0;i<numNew;i++) {
568 if (!newOpts[i])
569 continue;
570 if (nOut>0) {
571 strcat(orig,",");
572 strcat(orig,newOpts[i]);
573 }
574 else strcpy(orig,newOpts[i]);
575 nOut++;
576 }
577 return orig;
578 }
579 dawes 3.0
580 /***====================================================================***/
581
582 Bool
583 applyConfig(char *name)
584 {
585 FILE * fp;
586 Bool ok;
587
588 if ((fp=findFileInPath(name,""))==NULL)
589 return False;
590 ok= XkbCFParse(fp,XkbCFDflts,NULL,&cfgResult);
591 fclose(fp);
592 if (!ok) {
|
593 hohndel 3.2 ERR1("Couldn't find configuration file \"%s\"\n", name);
|
594 dawes 3.0 return False;
595 }
596 if (cfgResult.rules_file) {
597 trySetString(RULES_NDX,cfgResult.rules_file,FROM_CONFIG);
598 cfgResult.rules_file= NULL;
599 }
600 if (cfgResult.model) {
601 trySetString(MODEL_NDX,cfgResult.model,FROM_CONFIG);
602 cfgResult.model= NULL;
603 }
604 if (cfgResult.layout) {
605 trySetString(LAYOUT_NDX,cfgResult.layout,FROM_CONFIG);
606 cfgResult.layout= NULL;
607 }
608 if (cfgResult.variant) {
609 trySetString(VARIANT_NDX,cfgResult.variant,FROM_CONFIG);
610 cfgResult.variant= NULL;
611 }
612 if (cfgResult.options) {
613 addStringToOptions(cfgResult.options,&szOptions,&numOptions,&options);
614 cfgResult.options= NULL;
615 dawes 3.0 }
616 if (cfgResult.keymap) {
617 trySetString(KEYMAP_NDX,cfgResult.keymap,FROM_CONFIG);
618 cfgResult.keymap= NULL;
619 }
620 if (cfgResult.keycodes) {
621 trySetString(KEYCODES_NDX,cfgResult.keycodes,FROM_CONFIG);
622 cfgResult.keycodes= NULL;
623 }
624 if (cfgResult.geometry) {
625 trySetString(GEOMETRY_NDX,cfgResult.geometry,FROM_CONFIG);
626 cfgResult.geometry= NULL;
627 }
628 if (cfgResult.symbols) {
629 trySetString(SYMBOLS_NDX,cfgResult.symbols,FROM_CONFIG);
630 cfgResult.symbols= NULL;
631 }
632 if (cfgResult.types) {
633 trySetString(TYPES_NDX,cfgResult.types,FROM_CONFIG);
634 cfgResult.types= NULL;
635 }
636 dawes 3.0 if (cfgResult.compat) {
637 trySetString(COMPAT_NDX,cfgResult.compat,FROM_CONFIG);
638 cfgResult.compat= NULL;
639 }
640 if (verbose>5) {
641 MSG("After config file:\n");
642 dumpNames(True,True);
643 }
644 return True;
645 }
646
647 Bool
648 applyRules(void)
649 {
650 int i;
651 char * rfName;
652
653 if (svSrc[MODEL_NDX]||svSrc[LAYOUT_NDX]||svSrc[VARIANT_NDX]||options) {
654 char buf[PATH_MAX];
655 XkbComponentNamesRec rnames;
656
|
657 paulo 3.5 if(svSrc[VARIANT_NDX] < svSrc[LAYOUT_NDX])
658 svValue[VARIANT_NDX] = NULL;
|
659 dawes 3.0
660 rdefs.model= svValue[MODEL_NDX];
661 rdefs.layout= svValue[LAYOUT_NDX];
662 rdefs.variant= svValue[VARIANT_NDX];
663 if (options)
664 rdefs.options=stringFromOptions(rdefs.options,numOptions,options);
665
666 if (svSrc[RULES_NDX])
667 rfName= svValue[RULES_NDX];
668 else rfName= DFLT_XKB_RULES_FILE;
669
670 if (rfName[0]=='/') {
671 rules= XkbRF_Load(rfName,svValue[LOCALE_NDX],True,True);
672 }
673 else {
674 for (i=0;(i<numInclPath)&&(!rules);i++) {
675 if ((strlen(inclPath[i])+strlen(rfName)+8)>PATH_MAX) {
676 VMSG2(0,"Path too long (%s/rules/%s). Ignored.\n",
677 inclPath[i],rfName);
678 continue;
679 }
680 dawes 3.0 sprintf(buf,"%s/rules/%s",inclPath[i],svValue[RULES_NDX]);
681 rules= XkbRF_Load(buf,svValue[LOCALE_NDX],True,True);
682 }
683 }
684 if (!rules) {
685 ERR1("Couldn't find rules file (%s) \n",svValue[RULES_NDX]);
686 return False;
687 }
688 XkbRF_GetComponents(rules,&rdefs,&rnames);
689 if (rnames.keycodes) {
690 trySetString(KEYCODES_NDX,rnames.keycodes,FROM_RULES);
691 rnames.keycodes= NULL;
692 }
693 if (rnames.symbols) {
694 trySetString(SYMBOLS_NDX,rnames.symbols,FROM_RULES);
695 rnames.symbols= NULL;
696 }
697 if (rnames.types) {
698 trySetString(TYPES_NDX,rnames.types,FROM_RULES);
699 rnames.types= NULL;
700 }
701 dawes 3.0 if (rnames.compat) {
702 trySetString(COMPAT_NDX,rnames.compat,FROM_RULES);
703 rnames.compat= NULL;
704 }
705 if (rnames.geometry) {
706 trySetString(GEOMETRY_NDX,rnames.geometry,FROM_RULES);
707 rnames.geometry= NULL;
708 }
709 if (rnames.keymap) {
710 trySetString(KEYMAP_NDX,rnames.keymap,FROM_RULES);
711 rnames.keymap= NULL;
712 }
713 if (verbose>6) {
714 MSG1("Applied rules from %s:\n",svValue[RULES_NDX]);
|
715 paulo 3.5 dumpNames(True,False);
|
716 dawes 3.0 }
717 }
718 else if (verbose>6) {
719 MSG("No rules variables specified. Rules file ignored\n");
720 }
721 return True;
722 }
723
|
724 dawes 3.4 /* Primitive sanity check - filter out 'map names' (inside parenthesis) */
725 /* that can confuse xkbcomp parser */
|
726 dawes 3.9 static Bool
|
727 dawes 3.4 checkName(char *name, char* string)
728 {
729 char *i = name, *opar = NULL;
730 Bool ret = True;
731
732 if(!name)
733 return True;
734
735 while (*i){
736 if (opar == NULL) {
737 if (*i == '(')
738 opar = i;
739 } else {
740 if ((*i == '(') || (*i == '|') || (*i == '+')) {
741 ret = False;
742 break;
743 }
744 if (*i == ')')
745 opar = NULL;
746 }
747 i++;
748 dawes 3.4 }
749 if (opar)
750 ret = False;
751 if (!ret) {
752 char c;
753 int n = 1;
754 for(i = opar+1; *i && n; i++) {
755 if (*i == '(') n++;
756 if (*i == ')') n--;
757 }
758 if (*i) i++;
759 c = *i;
760 *i = '\0';
761 ERR1("Illegal map name '%s' ", opar);
762 *i = c;
763 ERR2("in %s name '%s'\n", string, name);
764 }
765 return ret;
766 }
|
767 dawes 3.0
|
768 dawes 3.7 void
769 printKeymap(void)
770 {
771 MSG("xkb_keymap {\n");
772 if (svValue[KEYCODES_NDX])
773 MSG1("\txkb_keycodes { include \"%s\"\t};\n",svValue[KEYCODES_NDX]);
774 if (svValue[TYPES_NDX])
775 MSG1("\txkb_types { include \"%s\"\t};\n",svValue[TYPES_NDX]);
776 if (svValue[COMPAT_NDX])
777 MSG1("\txkb_compat { include \"%s\"\t};\n",svValue[COMPAT_NDX]);
778 if (svValue[SYMBOLS_NDX])
779 MSG1("\txkb_symbols { include \"%s\"\t};\n",svValue[SYMBOLS_NDX]);
780 if (svValue[GEOMETRY_NDX])
781 MSG1("\txkb_geometry { include \"%s\"\t};\n",svValue[GEOMETRY_NDX]);
782 MSG("};\n");
783 }
784
|
785 dawes 3.0 Bool
786 applyComponentNames(void)
787 {
|
788 dawes 3.4 if(!checkName(svValue[TYPES_NDX], "types"))
789 return False;
790 if(!checkName(svValue[COMPAT_NDX], "compat"))
791 return False;
792 if(!checkName(svValue[SYMBOLS_NDX], "symbols"))
793 return False;
794 if(!checkName(svValue[KEYCODES_NDX], "keycodes"))
795 return False;
796 if(!checkName(svValue[GEOMETRY_NDX], "geometry"))
|
797 dawes 3.0 return False;
|
798 dawes 3.4 if(!checkName(svValue[KEYMAP_NDX], "keymap"))
|
799 dawes 3.0 return False;
|
800 dawes 3.4
|
801 dawes 3.0 if (verbose>5) {
802 MSG("Trying to build keymap using the following components:\n");
|
803 paulo 3.5 dumpNames(False,True);
|
804 dawes 3.0 }
|
805 dawes 3.7 if (dpy && !print) {
|
806 dawes 3.0 XkbComponentNamesRec cmdNames;
807 cmdNames.types= svValue[TYPES_NDX];
808 cmdNames.compat= svValue[COMPAT_NDX];
809 cmdNames.symbols= svValue[SYMBOLS_NDX];
810 cmdNames.keycodes= svValue[KEYCODES_NDX];
811 cmdNames.geometry= svValue[GEOMETRY_NDX];
812 cmdNames.keymap= svValue[KEYMAP_NDX];
813 xkb= XkbGetKeyboardByName(dpy,XkbUseCoreKbd,&cmdNames,
814 XkbGBN_AllComponentsMask,
815 XkbGBN_AllComponentsMask&(~XkbGBN_GeometryMask),
816 True);
817 if (!xkb) {
818 ERR("Error loading new keyboard description\n");
819 return False;
820 }
821 if (svValue[RULES_NDX] && (rdefs.model || rdefs.layout)) {
822 if (!XkbRF_SetNamesProp(dpy,svValue[RULES_NDX],&rdefs)) {
823 VMSG(0,"Error updating the XKB names property\n");
824 }
825 }
|
826 dawes 3.7 }
827 if (print) {
828 printKeymap();
|
829 dawes 3.0 }
830 return True;
831 }
832
833
834 int
835 main(int argc,char **argv)
836 {
837 if ((!parseArgs(argc,argv))||(!getDisplay(argc,argv)))
838 exit(-1);
839 svValue[LOCALE_NDX]= setlocale(LC_ALL,svValue[LOCALE_NDX]);
840 svSrc[LOCALE_NDX]= FROM_SERVER;
841 VMSG1(7,"locale is %s\n",svValue[LOCALE_NDX]);
|
842 dawes 3.4 if (dpy)
843 getServerValues();
|
844 dawes 3.0 if (svValue[CONFIG_NDX] && (!applyConfig(svValue[CONFIG_NDX])))
845 exit(-3);
846 if (!applyRules())
847 exit(-4);
848 if (!applyComponentNames())
849 exit(-5);
850 if (dpy)
851 XCloseDisplay(dpy);
|
852 hohndel 3.2 exit(0);
|
853 dawes 3.0 }
|