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>
37 #include <X11/extensions/XKMformat.h>
40 #include <X11/keysym.h>
41 #include <X11/Xproto.h>
46 #define XKBSRV_NEED_FILE_FUNCS 1
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_ssharp
) && (ks
<= XK_ydiaeresis
) &&
66 (ks
!= XK_division
))) {
71 if (((ks
>= XK_Aogonek
) && (ks
<= XK_Zabovedot
) && (ks
!= XK_breve
)) ||
72 ((ks
>= XK_Racute
) && (ks
<= XK_Tcedilla
))) {
75 if (((ks
>= XK_aogonek
) && (ks
<= XK_zabovedot
) && (ks
!= XK_ogonek
) &&
76 (ks
!= XK_caron
) && (ks
!= XK_doubleacute
)) || ((ks
>= XK_racute
)
84 if (((ks
>= XK_Hstroke
) && (ks
<= XK_Jcircumflex
)) ||
85 ((ks
>= XK_Cabovedot
) && (ks
<= XK_Scircumflex
))) {
88 if (((ks
>= XK_hstroke
) && (ks
<= XK_jcircumflex
)) ||
89 ((ks
>= XK_cabovedot
) && (ks
<= XK_scircumflex
))) {
94 if (((ks
>= XK_Rcedilla
) && (ks
<= XK_Tslash
)) ||
95 (ks
== XK_ENG
) || ((ks
>= XK_Amacron
) && (ks
<= XK_Umacron
))) {
99 ((ks
>= XK_rcedilla
) && (ks
<= XK_tslash
)) ||
100 (ks
== XK_eng
) || ((ks
>= XK_amacron
) && (ks
<= XK_umacron
))) {
104 case 18: /* latin 8 */
105 if ((ks
== XK_Wcircumflex
) ||
106 (ks
== XK_Ycircumflex
) ||
107 (ks
== XK_Babovedot
) ||
108 (ks
== XK_Dabovedot
) ||
109 (ks
== XK_Fabovedot
) ||
110 (ks
== XK_Mabovedot
) ||
111 (ks
== XK_Pabovedot
) ||
112 (ks
== XK_Sabovedot
) ||
113 (ks
== XK_Tabovedot
) ||
115 (ks
== XK_Wacute
) || (ks
== XK_Wdiaeresis
) || (ks
== XK_Ygrave
)) {
118 if ((ks
== XK_wcircumflex
) ||
119 (ks
== XK_ycircumflex
) ||
120 (ks
== XK_babovedot
) ||
121 (ks
== XK_dabovedot
) ||
122 (ks
== XK_fabovedot
) ||
123 (ks
== XK_mabovedot
) ||
124 (ks
== XK_pabovedot
) ||
125 (ks
== XK_sabovedot
) ||
126 (ks
== XK_tabovedot
) ||
128 (ks
== XK_wacute
) || (ks
== XK_wdiaeresis
) || (ks
== XK_ygrave
)) {
132 case 19: /* latin 9 */
133 if ((ks
== XK_OE
) || (ks
== XK_Ydiaeresis
)) {
144 /***===================================================================***/
147 XkbWriteSectionFromName(FILE * file
, const char *sectionName
, const char *name
)
149 fprintf(file
, " xkb_%-20s { include \"%s\" };\n", sectionName
, name
);
153 #define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
154 #define COMPLETE(n) ((n)&&(!NEED_DESC(n)))
158 _AddIncl(FILE * file
,
160 Bool topLevel
, Bool showImplicit
, int index
, void *priv
)
162 if ((priv
) && (strcmp((char *) priv
, "%") != 0))
163 fprintf(file
, " include \"%s\"\n", (char *) priv
);
168 XkbWriteXKBKeymapForNames(FILE * file
,
169 XkbComponentNamesPtr names
,
170 XkbDescPtr xkb
, unsigned want
, unsigned need
)
174 XkbNamesPtr old_names
;
176 unsigned wantNames
, wantConfig
, wantDflts
;
179 if (COMPLETE(names
->keycodes
))
180 complete
|= XkmKeyNamesMask
;
181 if (COMPLETE(names
->types
))
182 complete
|= XkmTypesMask
;
183 if (COMPLETE(names
->compat
))
184 complete
|= XkmCompatMapMask
;
185 if (COMPLETE(names
->symbols
))
186 complete
|= XkmSymbolsMask
;
187 if (COMPLETE(names
->geometry
))
188 complete
|= XkmGeometryMask
;
189 want
|= (complete
| need
);
190 if (want
& XkmSymbolsMask
)
191 want
|= XkmKeyNamesMask
| XkmTypesMask
;
197 old_names
= xkb
->names
;
200 /* Wow would it ever be neat if we didn't need this noise. */
201 if (xkb
->names
&& xkb
->names
->keys
)
202 xkb
->defined
|= XkmKeyNamesMask
;
203 if (xkb
->map
&& xkb
->map
->types
)
204 xkb
->defined
|= XkmTypesMask
;
206 xkb
->defined
|= XkmCompatMapMask
;
207 if (xkb
->map
&& xkb
->map
->num_syms
)
208 xkb
->defined
|= XkmSymbolsMask
;
210 xkb
->defined
|= XkmIndicatorsMask
;
212 xkb
->defined
|= XkmGeometryMask
;
218 wantConfig
= want
& (~complete
);
220 if (wantConfig
& XkmTypesMask
) {
221 if ((!xkb
->map
) || (xkb
->map
->num_types
< XkbNumRequiredTypes
))
222 wantConfig
&= ~XkmTypesMask
;
224 if (wantConfig
& XkmCompatMapMask
) {
225 if ((!xkb
->compat
) || (xkb
->compat
->num_si
< 1))
226 wantConfig
&= ~XkmCompatMapMask
;
228 if (wantConfig
& XkmSymbolsMask
) {
229 if ((!xkb
->map
) || (!xkb
->map
->key_sym_map
))
230 wantConfig
&= ~XkmSymbolsMask
;
232 if (wantConfig
& XkmIndicatorsMask
) {
233 if (!xkb
->indicators
)
234 wantConfig
&= ~XkmIndicatorsMask
;
236 if (wantConfig
& XkmKeyNamesMask
) {
237 if ((!xkb
->names
) || (!xkb
->names
->keys
))
238 wantConfig
&= ~XkmKeyNamesMask
;
240 if ((wantConfig
& XkmGeometryMask
) && (!xkb
->geom
))
241 wantConfig
&= ~XkmGeometryMask
;
246 complete
|= wantConfig
;
249 wantNames
= want
& (~complete
);
250 if ((xkb
!= NULL
) && (old_names
!= NULL
)) {
251 if (wantNames
& XkmTypesMask
) {
252 if (old_names
->types
!= None
) {
253 tmp
= NameForAtom(old_names
->types
);
254 names
->types
= Xstrdup(tmp
);
257 wantDflts
|= XkmTypesMask
;
259 complete
|= XkmTypesMask
;
261 if (wantNames
& XkmCompatMapMask
) {
262 if (old_names
->compat
!= None
) {
263 tmp
= NameForAtom(old_names
->compat
);
264 names
->compat
= Xstrdup(tmp
);
267 wantDflts
|= XkmCompatMapMask
;
268 complete
|= XkmCompatMapMask
;
270 if (wantNames
& XkmSymbolsMask
) {
271 if (old_names
->symbols
== None
)
273 tmp
= NameForAtom(old_names
->symbols
);
274 names
->symbols
= Xstrdup(tmp
);
275 complete
|= XkmSymbolsMask
;
277 if (wantNames
& XkmKeyNamesMask
) {
278 if (old_names
->keycodes
!= None
) {
279 tmp
= NameForAtom(old_names
->keycodes
);
280 names
->keycodes
= Xstrdup(tmp
);
283 wantDflts
|= XkmKeyNamesMask
;
284 complete
|= XkmKeyNamesMask
;
286 if (wantNames
& XkmGeometryMask
) {
287 if (old_names
->geometry
== None
)
289 tmp
= NameForAtom(old_names
->geometry
);
290 names
->geometry
= Xstrdup(tmp
);
291 complete
|= XkmGeometryMask
;
292 wantNames
&= ~XkmGeometryMask
;
295 if (complete
& XkmCompatMapMask
)
296 complete
|= XkmIndicatorsMask
| XkmVirtualModsMask
;
297 else if (complete
& (XkmSymbolsMask
| XkmTypesMask
))
298 complete
|= XkmVirtualModsMask
;
299 if (need
& (~complete
))
301 if ((complete
& XkmSymbolsMask
) &&
302 ((XkmKeyNamesMask
| XkmTypesMask
) & (~complete
)))
306 if (((complete
& XkmKeymapRequired
) == XkmKeymapRequired
) &&
307 ((complete
& (~XkmKeymapLegal
)) == 0)) {
308 fprintf(file
, "xkb_keymap \"default\" {\n");
310 else if (((complete
& XkmSemanticsRequired
) == XkmSemanticsRequired
) &&
311 ((complete
& (~XkmSemanticsLegal
)) == 0)) {
312 fprintf(file
, "xkb_semantics \"default\" {\n");
314 else if (((complete
& XkmLayoutRequired
) == XkmLayoutRequired
) &&
315 ((complete
& (~XkmLayoutLegal
)) == 0)) {
316 fprintf(file
, "xkb_layout \"default\" {\n");
318 else if (XkmSingleSection(complete
& (~XkmVirtualModsMask
))) {
325 wantNames
= complete
& (~(wantConfig
| wantDflts
));
326 if (wantConfig
& XkmKeyNamesMask
)
327 XkbWriteXKBKeycodes(file
, xkb
, FALSE
, FALSE
, _AddIncl
, names
->keycodes
);
328 else if (wantDflts
& XkmKeyNamesMask
)
329 fprintf(stderr
, "Default symbols not implemented yet!\n");
330 else if (wantNames
& XkmKeyNamesMask
)
331 XkbWriteSectionFromName(file
, "keycodes", names
->keycodes
);
333 if (wantConfig
& XkmTypesMask
)
334 XkbWriteXKBKeyTypes(file
, xkb
, FALSE
, FALSE
, _AddIncl
, names
->types
);
335 else if (wantDflts
& XkmTypesMask
)
336 fprintf(stderr
, "Default types not implemented yet!\n");
337 else if (wantNames
& XkmTypesMask
)
338 XkbWriteSectionFromName(file
, "types", names
->types
);
340 if (wantConfig
& XkmCompatMapMask
)
341 XkbWriteXKBCompatMap(file
, xkb
, FALSE
, FALSE
, _AddIncl
, names
->compat
);
342 else if (wantDflts
& XkmCompatMapMask
)
343 fprintf(stderr
, "Default interps not implemented yet!\n");
344 else if (wantNames
& XkmCompatMapMask
)
345 XkbWriteSectionFromName(file
, "compatibility", names
->compat
);
347 if (wantConfig
& XkmSymbolsMask
)
348 XkbWriteXKBSymbols(file
, xkb
, FALSE
, FALSE
, _AddIncl
, names
->symbols
);
349 else if (wantNames
& XkmSymbolsMask
)
350 XkbWriteSectionFromName(file
, "symbols", names
->symbols
);
352 if (wantConfig
& XkmGeometryMask
)
353 XkbWriteXKBGeometry(file
, xkb
, FALSE
, FALSE
, _AddIncl
, names
->geometry
);
354 else if (wantNames
& XkmGeometryMask
)
355 XkbWriteSectionFromName(file
, "geometry", names
->geometry
);
358 fprintf(file
, "};\n");
362 /***====================================================================***/
365 XkbFindKeycodeByName(XkbDescPtr xkb
, char *name
, Bool use_aliases
)
369 if ((!xkb
) || (!xkb
->names
) || (!xkb
->names
->keys
))
371 for (i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
372 if (strncmp(xkb
->names
->keys
[i
].name
, name
, XkbKeyNameLength
) == 0)
377 if (xkb
->geom
&& xkb
->geom
->key_aliases
) {
380 a
= xkb
->geom
->key_aliases
;
381 for (i
= 0; i
< xkb
->geom
->num_key_aliases
; i
++, a
++) {
382 if (strncmp(name
, a
->alias
, XkbKeyNameLength
) == 0)
383 return XkbFindKeycodeByName(xkb
, a
->real
, FALSE
);
386 if (xkb
->names
&& xkb
->names
->key_aliases
) {
389 a
= xkb
->names
->key_aliases
;
390 for (i
= 0; i
< xkb
->names
->num_key_aliases
; i
++, a
++) {
391 if (strncmp(name
, a
->alias
, XkbKeyNameLength
) == 0)
392 return XkbFindKeycodeByName(xkb
, a
->real
, FALSE
);
399 XkbConvertGetByNameComponents(Bool toXkm
, unsigned orig
)
405 if (orig
& XkbGBN_TypesMask
)
406 rtrn
|= XkmTypesMask
;
407 if (orig
& XkbGBN_CompatMapMask
)
408 rtrn
|= XkmCompatMapMask
;
409 if (orig
& XkbGBN_SymbolsMask
)
410 rtrn
|= XkmSymbolsMask
;
411 if (orig
& XkbGBN_IndicatorMapMask
)
412 rtrn
|= XkmIndicatorsMask
;
413 if (orig
& XkbGBN_KeyNamesMask
)
414 rtrn
|= XkmKeyNamesMask
;
415 if (orig
& XkbGBN_GeometryMask
)
416 rtrn
|= XkmGeometryMask
;
419 if (orig
& XkmTypesMask
)
420 rtrn
|= XkbGBN_TypesMask
;
421 if (orig
& XkmCompatMapMask
)
422 rtrn
|= XkbGBN_CompatMapMask
;
423 if (orig
& XkmSymbolsMask
)
424 rtrn
|= XkbGBN_SymbolsMask
;
425 if (orig
& XkmIndicatorsMask
)
426 rtrn
|= XkbGBN_IndicatorMapMask
;
427 if (orig
& XkmKeyNamesMask
)
428 rtrn
|= XkbGBN_KeyNamesMask
;
429 if (orig
& XkmGeometryMask
)
430 rtrn
|= XkbGBN_GeometryMask
;
432 rtrn
|= XkbGBN_OtherNamesMask
;
437 /***====================================================================***/
439 #define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/'))
442 XkbNameMatchesPattern(char *name
, char *ptrn
)
444 while (ptrn
[0] != '\0') {
445 if (name
[0] == '\0') {
446 if (ptrn
[0] == '*') {
452 if (ptrn
[0] == '?') {
453 if (UNMATCHABLE(name
[0]))
456 else if (ptrn
[0] == '*') {
457 if ((!UNMATCHABLE(name
[0])) &&
458 XkbNameMatchesPattern(name
+ 1, ptrn
))
460 return XkbNameMatchesPattern(name
, ptrn
+ 1);
462 else if (ptrn
[0] != name
[0])
467 /* if we get here, the pattern is exhausted (-:just like me:-) */
468 return name
[0] == '\0';