1 /************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
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.
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 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
36 #include <X11/Xfuncs.h>
40 #include <X11/keysym.h>
41 #include <X11/Xproto.h>
45 #include <X11/extensions/XKBstr.h>
46 #define XKBSRV_NEED_FILE_FUNCS 1
48 #include <X11/extensions/XKBgeom.h>
52 _XkbKSCheckCase(KeySym ks
)
56 set
= (ks
& (~0xff)) >> 8;
60 if (((ks
>=XK_A
)&&(ks
<=XK_Z
))||
61 ((ks
>=XK_Agrave
)&&(ks
<=XK_THORN
)&&(ks
!=XK_multiply
))) {
64 if (((ks
>=XK_a
)&&(ks
<=XK_z
))||
65 ((ks
>=XK_agrave
)&&(ks
<=XK_ydiaeresis
))) {
70 if (((ks
>=XK_Aogonek
)&&(ks
<=XK_Zabovedot
)&&(ks
!=XK_breve
))||
71 ((ks
>=XK_Racute
)&&(ks
<=XK_Tcedilla
))) {
74 if (((ks
>=XK_aogonek
)&&(ks
<=XK_zabovedot
)&&(ks
!=XK_caron
))||
75 ((ks
>=XK_racute
)&&(ks
<=XK_tcedilla
))) {
80 if (((ks
>=XK_Hstroke
)&&(ks
<=XK_Jcircumflex
))||
81 ((ks
>=XK_Cabovedot
)&&(ks
<=XK_Scircumflex
))) {
84 if (((ks
>=XK_hstroke
)&&(ks
<=XK_jcircumflex
))||
85 ((ks
>=XK_cabovedot
)&&(ks
<=XK_scircumflex
))) {
90 if (((ks
>=XK_Rcedilla
)&&(ks
<=XK_Tslash
))||
92 ((ks
>=XK_Amacron
)&&(ks
<=XK_Umacron
))) {
95 if (((ks
>=XK_rcedilla
)&&(ks
<=XK_tslash
))||
97 ((ks
>=XK_amacron
)&&(ks
<=XK_umacron
))) {
101 case 18: /* latin 8 */
102 if ((ks
==XK_Babovedot
)||
103 ((ks
>=XK_Dabovedot
)&&(ks
<=XK_Wacute
))||
104 ((ks
>=XK_Ygrave
)&&(ks
<=XK_Fabovedot
))||
108 (ks
==XK_Wdiaeresis
)||
109 ((ks
>=XK_Wcircumflex
)&&(ks
<=XK_Ycircumflex
))) {
112 if ((ks
==XK_babovedot
)||
116 ((ks
>=XK_wgrave
)&&(ks
<=XK_wacute
))||
118 ((ks
>=XK_wdiaeresis
)&&(ks
<=XK_ycircumflex
))) {
122 case 19: /* latin 9 */
123 if ((ks
==XK_OE
)||(ks
==XK_Ydiaeresis
)) {
134 /***===================================================================***/
137 XkbWriteSectionFromName(FILE *file
,char *sectionName
,char *name
)
139 fprintf(file
," xkb_%-20s { include \"%s\" };\n",sectionName
,name
);
143 #define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
144 #define COMPLETE(n) ((n)&&(!NEED_DESC(n)))
148 _AddIncl( FILE * file
,
149 XkbFileInfo
* result
,
155 if ((priv
)&&(strcmp((char *)priv
,"%")!=0))
156 fprintf(file
," include \"%s\"\n",(char *)priv
);
161 XkbWriteXKBKeymapForNames( FILE * file
,
162 XkbComponentNamesPtr names
,
170 XkbNamesPtr old_names
;
172 unsigned wantNames
,wantConfig
,wantDflts
;
175 bzero(&finfo
,sizeof(XkbFileInfo
));
178 if ((name
=names
->keymap
)==NULL
) name
= "default";
179 if (COMPLETE(names
->keycodes
)) complete
|= XkmKeyNamesMask
;
180 if (COMPLETE(names
->types
)) complete
|= XkmTypesMask
;
181 if (COMPLETE(names
->compat
)) complete
|= XkmCompatMapMask
;
182 if (COMPLETE(names
->symbols
)) complete
|= XkmSymbolsMask
;
183 if (COMPLETE(names
->geometry
)) complete
|= XkmGeometryMask
;
184 want
|= (complete
|need
);
185 if (want
&XkmSymbolsMask
)
186 want
|= XkmKeyNamesMask
|XkmTypesMask
;
192 old_names
= xkb
->names
;
196 if (!XkbDetermineFileType(&finfo
,XkbXKBFile
,NULL
))
199 else old_names
= NULL
;
201 wantConfig
= want
&(~complete
);
203 if (wantConfig
&XkmTypesMask
) {
204 if ((!xkb
->map
) || (xkb
->map
->num_types
<XkbNumRequiredTypes
))
205 wantConfig
&= ~XkmTypesMask
;
207 if (wantConfig
&XkmCompatMapMask
) {
208 if ((!xkb
->compat
) || (xkb
->compat
->num_si
<1))
209 wantConfig
&= ~XkmCompatMapMask
;
211 if (wantConfig
&XkmSymbolsMask
) {
212 if ((!xkb
->map
) || (!xkb
->map
->key_sym_map
))
213 wantConfig
&= ~XkmSymbolsMask
;
215 if (wantConfig
&XkmIndicatorsMask
) {
216 if (!xkb
->indicators
)
217 wantConfig
&= ~XkmIndicatorsMask
;
219 if (wantConfig
&XkmKeyNamesMask
) {
220 if ((!xkb
->names
)||(!xkb
->names
->keys
))
221 wantConfig
&= ~XkmKeyNamesMask
;
223 if ((wantConfig
&XkmGeometryMask
)&&(!xkb
->geom
))
224 wantConfig
&= ~XkmGeometryMask
;
229 complete
|= wantConfig
;
232 wantNames
= want
&(~complete
);
233 if ((xkb
!=NULL
) && (old_names
!=NULL
)) {
234 if (wantNames
&XkmTypesMask
) {
235 if (old_names
->types
!=None
) {
236 tmp
= XkbAtomGetString(dpy
,old_names
->types
);
237 names
->types
= _XkbDupString(tmp
);
240 wantDflts
|= XkmTypesMask
;
242 complete
|= XkmTypesMask
;
244 if (wantNames
&XkmCompatMapMask
) {
245 if (old_names
->compat
!=None
) {
246 tmp
= XkbAtomGetString(dpy
,old_names
->compat
);
247 names
->compat
= _XkbDupString(tmp
);
249 else wantDflts
|= XkmCompatMapMask
;
250 complete
|= XkmCompatMapMask
;
252 if (wantNames
&XkmSymbolsMask
) {
253 if (old_names
->symbols
==None
)
255 tmp
= XkbAtomGetString(dpy
,old_names
->symbols
);
256 names
->symbols
= _XkbDupString(tmp
);
257 complete
|= XkmSymbolsMask
;
259 if (wantNames
&XkmKeyNamesMask
) {
260 if (old_names
->keycodes
!=None
) {
261 tmp
= XkbAtomGetString(dpy
,old_names
->keycodes
);
262 names
->keycodes
= _XkbDupString(tmp
);
264 else wantDflts
|= XkmKeyNamesMask
;
265 complete
|= XkmKeyNamesMask
;
267 if (wantNames
&XkmGeometryMask
) {
268 if (old_names
->geometry
==None
)
270 tmp
= XkbAtomGetString(dpy
,old_names
->geometry
);
271 names
->geometry
= _XkbDupString(tmp
);
272 complete
|= XkmGeometryMask
;
273 wantNames
&= ~XkmGeometryMask
;
276 if (complete
&XkmCompatMapMask
)
277 complete
|= XkmIndicatorsMask
|XkmVirtualModsMask
;
278 else if (complete
&(XkmSymbolsMask
|XkmTypesMask
))
279 complete
|= XkmVirtualModsMask
;
280 if (need
& (~complete
))
282 if ((complete
&XkmSymbolsMask
)&&((XkmKeyNamesMask
|XkmTypesMask
)&(~complete
)))
286 if (((complete
&XkmKeymapRequired
)==XkmKeymapRequired
)&&
287 ((complete
&(~XkmKeymapLegal
))==0)) {
288 fprintf(file
,"xkb_keymap \"%s\" {\n",name
);
290 else if (((complete
&XkmSemanticsRequired
)==XkmSemanticsRequired
)&&
291 ((complete
&(~XkmSemanticsLegal
))==0)) {
292 fprintf(file
,"xkb_semantics \"%s\" {\n",name
);
294 else if (((complete
&XkmLayoutRequired
)==XkmLayoutRequired
)&&
295 ((complete
&(~XkmLayoutLegal
))==0)) {
296 fprintf(file
,"xkb_layout \"%s\" {\n",name
);
298 else if (XkmSingleSection(complete
&(~XkmVirtualModsMask
))) {
305 wantNames
= complete
&(~(wantConfig
|wantDflts
));
306 name
= names
->keycodes
;
307 if (wantConfig
&XkmKeyNamesMask
)
308 XkbWriteXKBKeycodes(file
,&finfo
,False
,False
,_AddIncl
,name
);
309 else if (wantDflts
&XkmKeyNamesMask
)
310 fprintf(stderr
,"Default symbols not implemented yet!\n");
311 else if (wantNames
&XkmKeyNamesMask
)
312 XkbWriteSectionFromName(file
,"keycodes",name
);
315 if (wantConfig
&XkmTypesMask
)
316 XkbWriteXKBKeyTypes(file
,&finfo
,False
,False
,_AddIncl
,name
);
317 else if (wantDflts
&XkmTypesMask
)
318 fprintf(stderr
,"Default types not implemented yet!\n");
319 else if (wantNames
&XkmTypesMask
)
320 XkbWriteSectionFromName(file
,"types",name
);
323 if (wantConfig
&XkmCompatMapMask
)
324 XkbWriteXKBCompatMap(file
,&finfo
,False
,False
,_AddIncl
,name
);
325 else if (wantDflts
&XkmCompatMapMask
)
326 fprintf(stderr
,"Default interps not implemented yet!\n");
327 else if (wantNames
&XkmCompatMapMask
)
328 XkbWriteSectionFromName(file
,"compatibility",name
);
330 name
= names
->symbols
;
331 if (wantConfig
&XkmSymbolsMask
)
332 XkbWriteXKBSymbols(file
,&finfo
,False
,False
,_AddIncl
,name
);
333 else if (wantNames
&XkmSymbolsMask
)
334 XkbWriteSectionFromName(file
,"symbols",name
);
336 name
= names
->geometry
;
337 if (wantConfig
&XkmGeometryMask
)
338 XkbWriteXKBGeometry(file
,&finfo
,False
,False
,_AddIncl
,name
);
339 else if (wantNames
&XkmGeometryMask
)
340 XkbWriteSectionFromName(file
,"geometry",name
);
343 fprintf(file
,"};\n");
347 /***====================================================================***/
350 XkbFindKeycodeByName(XkbDescPtr xkb
,char *name
,Bool use_aliases
)
354 if ((!xkb
)||(!xkb
->names
)||(!xkb
->names
->keys
))
356 for (i
=xkb
->min_key_code
;i
<=xkb
->max_key_code
;i
++) {
357 if (strncmp(xkb
->names
->keys
[i
].name
,name
,XkbKeyNameLength
)==0)
362 if (xkb
->geom
&& xkb
->geom
->key_aliases
) {
364 a
= xkb
->geom
->key_aliases
;
365 for (i
=0;i
<xkb
->geom
->num_key_aliases
;i
++,a
++) {
366 if (strncmp(name
,a
->alias
,XkbKeyNameLength
)==0)
367 return XkbFindKeycodeByName(xkb
,a
->real
,False
);
370 if (xkb
->names
&& xkb
->names
->key_aliases
) {
372 a
= xkb
->names
->key_aliases
;
373 for (i
=0;i
<xkb
->names
->num_key_aliases
;i
++,a
++) {
374 if (strncmp(name
,a
->alias
,XkbKeyNameLength
)==0)
375 return XkbFindKeycodeByName(xkb
,a
->real
,False
);
383 XkbConvertGetByNameComponents(Bool toXkm
,unsigned orig
)
389 if (orig
&XkbGBN_TypesMask
) rtrn
|= XkmTypesMask
;
390 if (orig
&XkbGBN_CompatMapMask
) rtrn
|= XkmCompatMapMask
;
391 if (orig
&XkbGBN_SymbolsMask
) rtrn
|= XkmSymbolsMask
;
392 if (orig
&XkbGBN_IndicatorMapMask
) rtrn
|= XkmIndicatorsMask
;
393 if (orig
&XkbGBN_KeyNamesMask
) rtrn
|= XkmKeyNamesMask
;
394 if (orig
&XkbGBN_GeometryMask
) rtrn
|= XkmGeometryMask
;
397 if (orig
&XkmTypesMask
) rtrn
|= XkbGBN_TypesMask
;
398 if (orig
&XkmCompatMapMask
) rtrn
|= XkbGBN_CompatMapMask
;
399 if (orig
&XkmSymbolsMask
) rtrn
|= XkbGBN_SymbolsMask
;
400 if (orig
&XkmIndicatorsMask
) rtrn
|= XkbGBN_IndicatorMapMask
;
401 if (orig
&XkmKeyNamesMask
) rtrn
|= XkbGBN_KeyNamesMask
;
402 if (orig
&XkmGeometryMask
) rtrn
|= XkbGBN_GeometryMask
;
403 if (orig
!=0) rtrn
|= XkbGBN_OtherNamesMask
;
409 XkbDetermineFileType(XkbFileInfoPtr finfo
,int format
,int *opts_missing
)
414 if ((!finfo
)||(!finfo
->xkb
))
420 if ((xkb
->names
)&&(xkb
->names
->keys
)) present
|= XkmKeyNamesMask
;
421 if ((xkb
->map
)&&(xkb
->map
->types
)) present
|= XkmTypesMask
;
422 if (xkb
->compat
) present
|= XkmCompatMapMask
;
423 if ((xkb
->map
)&&(xkb
->map
->num_syms
>1)) present
|= XkmSymbolsMask
;
424 if (xkb
->indicators
) present
|= XkmIndicatorsMask
;
425 if (xkb
->geom
) present
|= XkmGeometryMask
;
428 else switch (present
) {
429 case XkmKeyNamesMask
:
430 finfo
->type
= XkmKeyNamesIndex
;
431 finfo
->defined
= present
;
434 finfo
->type
= XkmTypesIndex
;
435 finfo
->defined
= present
;
437 case XkmCompatMapMask
:
438 finfo
->type
= XkmCompatMapIndex
;
439 finfo
->defined
= present
;
442 if (format
!=XkbXKMFile
) {
443 finfo
->type
= XkmSymbolsIndex
;
444 finfo
->defined
= present
;
448 case XkmGeometryMask
:
449 finfo
->type
= XkmGeometryIndex
;
450 finfo
->defined
= present
;
453 if ((present
&(~XkmSemanticsLegal
))==0) {
454 if ((XkmSemanticsRequired
&present
)==XkmSemanticsRequired
) {
456 *opts_missing
= XkmSemanticsOptional
&(~present
);
457 finfo
->type
= XkmSemanticsFile
;
458 finfo
->defined
= present
;
462 else if ((present
&(~XkmLayoutLegal
))==0) {
463 if ((XkmLayoutRequired
&present
)==XkmLayoutRequired
) {
465 *opts_missing
= XkmLayoutOptional
&(~present
);
466 finfo
->type
= XkmLayoutFile
;
467 finfo
->defined
= present
;
471 else if ((present
&(~XkmKeymapLegal
))==0) {
472 if ((XkmKeymapRequired
&present
)==XkmKeymapRequired
) {
474 *opts_missing
= XkmKeymapOptional
&(~present
);
475 finfo
->type
= XkmKeymapFile
;
476 finfo
->defined
= present
;
483 /* all latin-1 alphanumerics, plus parens, slash, minus, underscore and */
486 static unsigned char componentSpecLegal
[] = {
487 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
488 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
494 XkbEnsureSafeMapName(char *name
)
498 while (*name
!='\0') {
499 if ((componentSpecLegal
[(*name
)/8]&(1<<((*name
)%8)))==0)
506 /***====================================================================***/
508 #define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/'))
511 XkbNameMatchesPattern(char *name
,char *ptrn
)
513 while (ptrn
[0]!='\0') {
522 if (UNMATCHABLE(name
[0]))
525 else if (ptrn
[0]=='*') {
526 if ((!UNMATCHABLE(name
[0]))&&XkbNameMatchesPattern(name
+1,ptrn
))
528 return XkbNameMatchesPattern(name
,ptrn
+1);
530 else if (ptrn
[0]!=name
[0])
535 /* if we get here, the pattern is exhausted (-:just like me:-) */
536 return (name
[0]=='\0');