Bug Summary

File:symbols.c
Location:line 452, column 33
Description:Dereference of null pointer (loaded from variable 'use')

Annotated Source Code

1/************************************************************
2 Copyright (c) 1994 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 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27#include "xkbcomp.h"
28#include "tokens.h"
29#include "expr.h"
30#include "parseutils.h"
31
32#include <X11/keysym.h>
33#include <X11/Xutil.h>
34#include <stdlib.h>
35
36#include "expr.h"
37#include "vmod.h"
38#include "action.h"
39#include "keycodes.h"
40#include "misc.h"
41#include "alias.h"
42
43/***====================================================================***/
44
45#define RepeatYes1 1
46#define RepeatNo0 0
47#define RepeatUndefined~((unsigned)0) ~((unsigned)0)
48
49#define _Key_Syms(1<<0) (1<<0)
50#define _Key_Acts(1<<1) (1<<1)
51#define _Key_Repeat(1<<2) (1<<2)
52#define _Key_Behavior(1<<3) (1<<3)
53#define _Key_Type_Dflt(1<<4) (1<<4)
54#define _Key_Types(1<<5) (1<<5)
55#define _Key_GroupInfo(1<<6) (1<<6)
56#define _Key_VModMap(1<<7) (1<<7)
57
58typedef struct _KeyInfo
59{
60 CommonInfo defs;
61 unsigned long name; /* the 4 chars of the key name, as long */
62 unsigned char groupInfo;
63 unsigned char typesDefined;
64 unsigned char symsDefined;
65 unsigned char actsDefined;
66 short numLevels[XkbNumKbdGroups4];
67 KeySym *syms[XkbNumKbdGroups4];
68 XkbAction *acts[XkbNumKbdGroups4];
69 Atom types[XkbNumKbdGroups4];
70 unsigned repeat;
71 XkbBehavior behavior;
72 unsigned short vmodmap;
73 unsigned long nameForOverlayKey;
74 unsigned long allowNone;
75 Atom dfltType;
76} KeyInfo;
77
78/**
79 * Init the given key info to sane values.
80 */
81static void
82InitKeyInfo(KeyInfo * info)
83{
84 register int i;
85 static char dflt[4] = "*";
86
87 info->defs.defined = 0;
88 info->defs.fileID = 0;
89 info->defs.merge = MergeOverride2;
90 info->defs.next = NULL((void*)0);
91 info->name = KeyNameToLong(dflt)((((unsigned long)dflt[0])<<24)|(((unsigned long)dflt[1
])<<16)|(((unsigned long)dflt[2])<<8)|dflt[3])
;
92 info->groupInfo = 0;
93 info->typesDefined = info->symsDefined = info->actsDefined = 0;
94 for (i = 0; i < XkbNumKbdGroups4; i++)
95 {
96 info->numLevels[i] = 0;
97 info->types[i] = None0L;
98 info->syms[i] = NULL((void*)0);
99 info->acts[i] = NULL((void*)0);
100 }
101 info->dfltType = None0L;
102 info->behavior.type = XkbKB_Default0x00;
103 info->behavior.data = 0;
104 info->vmodmap = 0;
105 info->nameForOverlayKey = 0;
106 info->repeat = RepeatUndefined~((unsigned)0);
107 info->allowNone = 0;
108 return;
109}
110
111/**
112 * Free memory associated with this key info and reset to sane values.
113 */
114static void
115FreeKeyInfo(KeyInfo * info)
116{
117 register int i;
118
119 info->defs.defined = 0;
120 info->defs.fileID = 0;
121 info->defs.merge = MergeOverride2;
122 info->defs.next = NULL((void*)0);
123 info->groupInfo = 0;
124 info->typesDefined = info->symsDefined = info->actsDefined = 0;
125 for (i = 0; i < XkbNumKbdGroups4; i++)
126 {
127 info->numLevels[i] = 0;
128 info->types[i] = None0L;
129 if (info->syms[i] != NULL((void*)0))
130 uFree(info->syms[i]);
131 info->syms[i] = NULL((void*)0);
132 if (info->acts[i] != NULL((void*)0))
133 uFree(info->acts[i]);
134 info->acts[i] = NULL((void*)0);
135 }
136 info->dfltType = None0L;
137 info->behavior.type = XkbKB_Default0x00;
138 info->behavior.data = 0;
139 info->vmodmap = 0;
140 info->nameForOverlayKey = 0;
141 info->repeat = RepeatUndefined~((unsigned)0);
142 info->allowNone = 0;
143 return;
144}
145
146/**
147 * Copy old into new, optionally reset old to 0.
148 * If old is reset, new simply re-uses old's memory. Otherwise, the memory is
149 * newly allocated and new points to the new memory areas.
150 */
151static Boolint
152CopyKeyInfo(KeyInfo * old, KeyInfo * new, Boolint clearOld)
153{
154 register int i;
155
156 *new = *old;
157 new->defs.next = NULL((void*)0);
158 if (clearOld)
159 {
160 for (i = 0; i < XkbNumKbdGroups4; i++)
161 {
162 old->numLevels[i] = 0;
163 old->syms[i] = NULL((void*)0);
164 old->acts[i] = NULL((void*)0);
165 }
166 }
167 else
168 {
169 int width;
170 for (i = 0; i < XkbNumKbdGroups4; i++)
171 {
172 width = new->numLevels[i];
173 if (old->syms[i] != NULL((void*)0))
174 {
175 new->syms[i] = uTypedCalloc(width, KeySym)((KeySym *)uCalloc((unsigned)width,(unsigned)sizeof(KeySym)));
176 if (!new->syms[i])
177 {
178 new->syms[i] = NULL((void*)0);
179 new->numLevels[i] = 0;
180 return False0;
181 }
182 memcpy((char *) new->syms[i], (char *) old->syms[i],
183 width * sizeof(KeySym));
184 }
185 if (old->acts[i] != NULL((void*)0))
186 {
187 new->acts[i] = uTypedCalloc(width, XkbAction)((XkbAction *)uCalloc((unsigned)width,(unsigned)sizeof(XkbAction
)))
;
188 if (!new->acts[i])
189 {
190 new->acts[i] = NULL((void*)0);
191 return False0;
192 }
193 memcpy((char *) new->acts[i], (char *) old->acts[i],
194 width * sizeof(XkbAction));
195 }
196 }
197 }
198 return True1;
199}
200
201/***====================================================================***/
202
203typedef struct _ModMapEntry
204{
205 CommonInfo defs;
206 Boolint haveSymbol;
207 int modifier;
208 union
209 {
210 unsigned long keyName;
211 KeySym keySym;
212 } u;
213} ModMapEntry;
214
215#define SYMBOLS_INIT_SIZE110 110
216#define SYMBOLS_CHUNK20 20
217typedef struct _SymbolsInfo
218{
219 char *name; /* e.g. pc+us+inet(evdev) */
220 int errorCount;
221 unsigned fileID;
222 unsigned merge;
223 unsigned explicit_group;
224 unsigned groupInfo;
225 unsigned szKeys;
226 unsigned nKeys;
227 KeyInfo *keys;
228 KeyInfo dflt;
229 VModInfo vmods;
230 ActionInfo *action;
231 Atom groupNames[XkbNumKbdGroups4];
232
233 ModMapEntry *modMap;
234 AliasInfo *aliases;
235} SymbolsInfo;
236
237static void
238InitSymbolsInfo(SymbolsInfo * info, XkbDescPtr xkb)
239{
240 register int i;
241
242 tok_ONE_LEVEL = XkbInternAtom(NULL((void*)0), "ONE_LEVEL", False0);
243 tok_TWO_LEVEL = XkbInternAtom(NULL((void*)0), "TWO_LEVEL", False0);
244 tok_KEYPAD = XkbInternAtom(NULL((void*)0), "KEYPAD", False0);
245 info->name = NULL((void*)0);
246 info->explicit_group = 0;
247 info->errorCount = 0;
248 info->fileID = 0;
249 info->merge = MergeOverride2;
250 info->groupInfo = 0;
251 info->szKeys = SYMBOLS_INIT_SIZE110;
252 info->nKeys = 0;
253 info->keys = uTypedCalloc(SYMBOLS_INIT_SIZE, KeyInfo)((KeyInfo *)uCalloc((unsigned)110,(unsigned)sizeof(KeyInfo)));
254 info->modMap = NULL((void*)0);
255 for (i = 0; i < XkbNumKbdGroups4; i++)
256 info->groupNames[i] = None0L;
257 InitKeyInfo(&info->dflt);
258 InitVModInfo(&info->vmods, xkb);
259 info->action = NULL((void*)0);
260 info->aliases = NULL((void*)0);
261 return;
262}
263
264static void
265FreeSymbolsInfo(SymbolsInfo * info)
266{
267 register int i;
268
269 if (info->name)
270 uFree(info->name);
271 info->name = NULL((void*)0);
272 if (info->keys)
273 {
274 for (i = 0; i < info->nKeys; i++)
275 {
276 FreeKeyInfo(&info->keys[i]);
277 }
278 uFree(info->keys);
279 info->keys = NULL((void*)0);
280 }
281 if (info->modMap)
282 {
283 ClearCommonInfo(&info->modMap->defs);
284 info->modMap = NULL((void*)0);
285 }
286 if (info->aliases)
287 {
288 ClearAliases(&info->aliases);
289 info->aliases = NULL((void*)0);
290 }
291 bzero((char *) info, sizeof(SymbolsInfo))memset((char *) info,0,sizeof(SymbolsInfo));
292 return;
293}
294
295static Boolint
296ResizeKeyGroup(KeyInfo * key,
297 unsigned group, unsigned atLeastSize, Boolint forceActions)
298{
299 Boolint tooSmall;
300 unsigned newWidth;
301
302 tooSmall = (key->numLevels[group] < atLeastSize);
303 if (tooSmall)
304 newWidth = atLeastSize;
305 else
306 newWidth = key->numLevels[group];
307
308 if ((key->syms[group] == NULL((void*)0)) || tooSmall)
309 {
310 key->syms[group] = uTypedRecalloc(key->syms[group],((KeySym *)uRecalloc((Opaque)key->syms[group],((unsigned)key
->numLevels[group]),((unsigned)newWidth),sizeof(KeySym)))
311 key->numLevels[group], newWidth,((KeySym *)uRecalloc((Opaque)key->syms[group],((unsigned)key
->numLevels[group]),((unsigned)newWidth),sizeof(KeySym)))
312 KeySym)((KeySym *)uRecalloc((Opaque)key->syms[group],((unsigned)key
->numLevels[group]),((unsigned)newWidth),sizeof(KeySym)))
;
313 if (!key->syms[group])
314 return False0;
315 }
316 if (((forceActions) && (tooSmall || (key->acts[group] == NULL((void*)0)))) ||
317 (tooSmall && (key->acts[group] != NULL((void*)0))))
318 {
319 key->acts[group] = uTypedRecalloc(key->acts[group],((XkbAction *)uRecalloc((Opaque)key->acts[group],((unsigned
)key->numLevels[group]),((unsigned)newWidth),sizeof(XkbAction
)))
320 key->numLevels[group], newWidth,((XkbAction *)uRecalloc((Opaque)key->acts[group],((unsigned
)key->numLevels[group]),((unsigned)newWidth),sizeof(XkbAction
)))
321 XkbAction)((XkbAction *)uRecalloc((Opaque)key->acts[group],((unsigned
)key->numLevels[group]),((unsigned)newWidth),sizeof(XkbAction
)))
;
322 if (!key->acts[group])
323 return False0;
324 }
325 key->numLevels[group] = newWidth;
326 return True1;
327}
328
329static Boolint
330MergeKeyGroups(SymbolsInfo * info,
331 KeyInfo * into, KeyInfo * from, unsigned group)
332{
333 KeySym *resultSyms;
334 XkbAction *resultActs;
335 int resultWidth;
336 register int i;
337 Boolint report, clobber;
338
339 clobber = (from->defs.merge != MergeAugment1);
340 report = (warningLevel > 9) ||
1
Assuming 'warningLevel' is <= 9
341 ((into->defs.fileID == from->defs.fileID) && (warningLevel > 0));
342 if (into->numLevels[group] >= from->numLevels[group])
2
Taking false branch
343 {
344 resultSyms = into->syms[group];
345 resultActs = into->acts[group];
346 resultWidth = into->numLevels[group];
347 }
348 else
349 {
350 resultSyms = from->syms[group];
351 resultActs = from->acts[group];
352 resultWidth = from->numLevels[group];
353 }
354 if (resultSyms == NULL((void*)0))
3
Assuming 'resultSyms' is not equal to null
4
Taking false branch
355 {
356 resultSyms = uTypedCalloc(resultWidth, KeySym)((KeySym *)uCalloc((unsigned)resultWidth,(unsigned)sizeof(KeySym
)))
;
357 if (!resultSyms)
358 {
359 WSGOuInternalError("Could not allocate symbols for group merge\n");
360 ACTION2uAction("Group %d of key %s not merged\n", group,
361 longText(into->name, XkbMessage3));
362 return False0;
363 }
364 }
365 if ((resultActs == NULL((void*)0)) && (into->acts[group] || from->acts[group]))
5
Assuming 'resultActs' is not equal to null
6
Taking false branch
366 {
367 resultActs = uTypedCalloc(resultWidth, XkbAction)((XkbAction *)uCalloc((unsigned)resultWidth,(unsigned)sizeof(
XkbAction)))
;
368 if (!resultActs)
369 {
370 WSGOuInternalError("Could not allocate actions for group merge\n");
371 ACTION2uAction("Group %d of key %s not merged\n", group,
372 longText(into->name, XkbMessage3));
373 return False0;
374 }
375 }
376 for (i = 0; i < resultWidth; i++)
7
Assuming 'i' is < 'resultWidth'
8
Loop condition is true. Entering loop body
377 {
378 KeySym fromSym, toSym;
379 if (from->syms[group] && (i < from->numLevels[group]))
9
Taking false branch
380 fromSym = from->syms[group][i];
381 else
382 fromSym = NoSymbol0L;
383 if (into->syms[group] && (i < into->numLevels[group]))
10
Taking false branch
384 toSym = into->syms[group][i];
385 else
386 toSym = NoSymbol0L;
387 if ((fromSym == NoSymbol0L) || (fromSym == toSym))
11
Taking true branch
388 resultSyms[i] = toSym;
389 else if (toSym == NoSymbol0L)
390 resultSyms[i] = fromSym;
391 else
392 {
393 KeySym use, ignore;
394 if (clobber)
395 {
396 use = fromSym;
397 ignore = toSym;
398 }
399 else
400 {
401 use = toSym;
402 ignore = fromSym;
403 }
404 if (report)
405 {
406 WARN3uWarning
407 ("Multiple symbols for level %d/group %d on key %s\n",
408 i + 1, group + 1, longText(into->name, XkbMessage3));
409 ACTION2uAction("Using %s, ignoring %s\n",
410 XkbKeysymText(use, XkbMessage3),
411 XkbKeysymText(ignore, XkbMessage3));
412 }
413 resultSyms[i] = use;
414 }
415 if (resultActs != NULL((void*)0))
12
Taking true branch
416 {
417 XkbAction *fromAct, *toAct;
418 fromAct = (from->acts[group] ? &from->acts[group][i] : NULL((void*)0));
13
'?' condition is false
419 toAct = (into->acts[group] ? &into->acts[group][i] : NULL((void*)0));
14
'?' condition is false
420 if (((fromAct == NULL((void*)0)) || (fromAct->type == XkbSA_NoAction0x00))
15
Taking false branch
421 && (toAct != NULL((void*)0)))
422 {
423 resultActs[i] = *toAct;
424 }
425 else if (((toAct == NULL((void*)0)) || (toAct->type == XkbSA_NoAction0x00))
16
Taking false branch
426 && (fromAct != NULL((void*)0)))
427 {
428 resultActs[i] = *fromAct;
429 }
430 else
431 {
432 XkbAction *use, *ignore;
433 if (clobber)
17
Taking false branch
434 {
435 use = fromAct;
436 ignore = toAct;
437 }
438 else
439 {
440 use = toAct;
441 ignore = fromAct;
442 }
443 if (report)
18
Taking false branch
444 {
445 WARN3uWarning
446 ("Multiple actions for level %d/group %d on key %s\n",
447 i + 1, group + 1, longText(into->name, XkbMessage3));
448 ACTION2uAction("Using %s, ignoring %s\n",
449 XkbActionTypeText(use->type, XkbMessage3),
450 XkbActionTypeText(ignore->type, XkbMessage3));
451 }
452 resultActs[i] = *use;
19
Dereference of null pointer (loaded from variable 'use')
453 }
454 }
455 }
456 if ((into->syms[group] != NULL((void*)0)) && (resultSyms != into->syms[group]))
457 uFree(into->syms[group]);
458 if ((from->syms[group] != NULL((void*)0)) && (resultSyms != from->syms[group]))
459 uFree(from->syms[group]);
460 if ((into->acts[group] != NULL((void*)0)) && (resultActs != into->acts[group]))
461 uFree(into->acts[group]);
462 if ((from->acts[group] != NULL((void*)0)) && (resultActs != from->acts[group]))
463 uFree(from->acts[group]);
464 into->numLevels[group] = resultWidth;
465 into->syms[group] = resultSyms;
466 from->syms[group] = NULL((void*)0);
467 into->acts[group] = resultActs;
468 from->acts[group] = NULL((void*)0);
469 into->symsDefined |= (1 << group);
470 from->symsDefined &= ~(1 << group);
471 into->actsDefined |= (1 << group);
472 from->actsDefined &= ~(1 << group);
473 return True1;
474}
475
476static Boolint
477MergeKeys(SymbolsInfo * info, KeyInfo * into, KeyInfo * from)
478{
479 register int i;
480 unsigned collide = 0;
481 Boolint report;
482
483 if (from->defs.merge == MergeReplace3)
484 {
485 for (i = 0; i < XkbNumKbdGroups4; i++)
486 {
487 if (into->numLevels[i] != 0)
488 {
489 if (into->syms[i])
490 uFree(into->syms[i]);
491 if (into->acts[i])
492 uFree(into->acts[i]);
493 }
494 }
495 *into = *from;
496 bzero(from, sizeof(KeyInfo))memset(from,0,sizeof(KeyInfo));
497 return True1;
498 }
499 report = ((warningLevel > 9) ||
500 ((into->defs.fileID == from->defs.fileID)
501 && (warningLevel > 0)));
502 for (i = 0; i < XkbNumKbdGroups4; i++)
503 {
504 if (from->numLevels[i] > 0)
505 {
506 if (into->numLevels[i] == 0)
507 {
508 into->numLevels[i] = from->numLevels[i];
509 into->syms[i] = from->syms[i];
510 into->acts[i] = from->acts[i];
511 into->symsDefined |= (1 << i);
512 from->syms[i] = NULL((void*)0);
513 from->acts[i] = NULL((void*)0);
514 from->numLevels[i] = 0;
515 from->symsDefined &= ~(1 << i);
516 if (into->syms[i])
517 into->defs.defined |= _Key_Syms(1<<0);
518 if (into->acts[i])
519 into->defs.defined |= _Key_Acts(1<<1);
520 }
521 else
522 {
523 if (report)
524 {
525 if (into->syms[i])
526 collide |= _Key_Syms(1<<0);
527 if (into->acts[i])
528 collide |= _Key_Acts(1<<1);
529 }
530 MergeKeyGroups(info, into, from, (unsigned) i);
531 }
532 }
533 if (from->types[i] != None0L)
534 {
535 if ((into->types[i] != None0L) && (report) &&
536 (into->types[i] != from->types[i]))
537 {
538 Atom use, ignore;
539 collide |= _Key_Types(1<<5);
540 if (from->defs.merge != MergeAugment1)
541 {
542 use = from->types[i];
543 ignore = into->types[i];
544 }
545 else
546 {
547 use = into->types[i];
548 ignore = from->types[i];
549 }
550 WARN2uWarning
551 ("Multiple definitions for group %d type of key %s\n",
552 i, longText(into->name, XkbMessage3));
553 ACTION2uAction("Using %s, ignoring %s\n",
554 XkbAtomText(NULL((void*)0), use, XkbMessage3),
555 XkbAtomText(NULL((void*)0), ignore, XkbMessage3));
556 }
557 if ((from->defs.merge != MergeAugment1)
558 || (into->types[i] == None0L))
559 {
560 into->types[i] = from->types[i];
561 }
562 }
563 }
564 if (UseNewField(_Key_Behavior(1<<3), &into->defs, &from->defs, &collide))
565 {
566 into->behavior = from->behavior;
567 into->nameForOverlayKey = from->nameForOverlayKey;
568 into->defs.defined |= _Key_Behavior(1<<3);
569 }
570 if (UseNewField(_Key_VModMap(1<<7), &into->defs, &from->defs, &collide))
571 {
572 into->vmodmap = from->vmodmap;
573 into->defs.defined |= _Key_VModMap(1<<7);
574 }
575 if (UseNewField(_Key_Repeat(1<<2), &into->defs, &from->defs, &collide))
576 {
577 into->repeat = from->repeat;
578 into->defs.defined |= _Key_Repeat(1<<2);
579 }
580 if (UseNewField(_Key_Type_Dflt(1<<4), &into->defs, &from->defs, &collide))
581 {
582 into->dfltType = from->dfltType;
583 into->defs.defined |= _Key_Type_Dflt(1<<4);
584 }
585 if (UseNewField(_Key_GroupInfo(1<<6), &into->defs, &from->defs, &collide))
586 {
587 into->groupInfo = from->groupInfo;
588 into->defs.defined |= _Key_GroupInfo(1<<6);
589 }
590 if (collide)
591 {
592 WARN1uWarning("Symbol map for key %s redefined\n",
593 longText(into->name, XkbMessage3));
594 ACTION1uAction("Using %s definition for conflicting fields\n",
595 (from->defs.merge == MergeAugment1 ? "first" : "last"));
596 }
597 return True1;
598}
599
600static Boolint
601AddKeySymbols(SymbolsInfo * info, KeyInfo * key, XkbDescPtr xkb)
602{
603 register int i;
604 unsigned long real_name;
605
606 for (i = 0; i < info->nKeys; i++)
607 {
608 if (info->keys[i].name == key->name)
609 return MergeKeys(info, &info->keys[i], key);
610 }
611 if (FindKeyNameForAlias(xkb, key->name, &real_name))
612 {
613 for (i = 0; i < info->nKeys; i++)
614 {
615 if (info->keys[i].name == real_name)
616 return MergeKeys(info, &info->keys[i], key);
617 }
618 }
619 if (info->nKeys >= info->szKeys)
620 {
621 info->szKeys += SYMBOLS_CHUNK20;
622 info->keys =
623 uTypedRecalloc(info->keys, info->nKeys, info->szKeys, KeyInfo)((KeyInfo *)uRecalloc((Opaque)info->keys,((unsigned)info->
nKeys),((unsigned)info->szKeys),sizeof(KeyInfo)))
;
624 if (!info->keys)
625 {
626 WSGOuInternalError("Could not allocate key symbols descriptions\n");
627 ACTIONuAction("Some key symbols definitions may be lost\n");
628 return False0;
629 }
630 }
631 return CopyKeyInfo(key, &info->keys[info->nKeys++], True1);
632}
633
634static Boolint
635AddModMapEntry(SymbolsInfo * info, ModMapEntry * new)
636{
637 ModMapEntry *mm;
638 Boolint clobber;
639
640 clobber = (new->defs.merge != MergeAugment1);
641 for (mm = info->modMap; mm != NULL((void*)0); mm = (ModMapEntry *) mm->defs.next)
642 {
643 if (new->haveSymbol && mm->haveSymbol
644 && (new->u.keySym == mm->u.keySym))
645 {
646 unsigned use, ignore;
647 if (mm->modifier != new->modifier)
648 {
649 if (clobber)
650 {
651 use = new->modifier;
652 ignore = mm->modifier;
653 }
654 else
655 {
656 use = mm->modifier;
657 ignore = new->modifier;
658 }
659 ERROR1uError
660 ("%s added to symbol map for multiple modifiers\n",
661 XkbKeysymText(new->u.keySym, XkbMessage3));
662 ACTION2uAction("Using %s, ignoring %s.\n",
663 XkbModIndexText(use, XkbMessage3),
664 XkbModIndexText(ignore, XkbMessage3));
665 mm->modifier = use;
666 }
667 return True1;
668 }
669 if ((!new->haveSymbol) && (!mm->haveSymbol) &&
670 (new->u.keyName == mm->u.keyName))
671 {
672 unsigned use, ignore;
673 if (mm->modifier != new->modifier)
674 {
675 if (clobber)
676 {
677 use = new->modifier;
678 ignore = mm->modifier;
679 }
680 else
681 {
682 use = mm->modifier;
683 ignore = new->modifier;
684 }
685 ERROR1uError("Key %s added to map for multiple modifiers\n",
686 longText(new->u.keyName, XkbMessage3));
687 ACTION2uAction("Using %s, ignoring %s.\n",
688 XkbModIndexText(use, XkbMessage3),
689 XkbModIndexText(ignore, XkbMessage3));
690 mm->modifier = use;
691 }
692 return True1;
693 }
694 }
695 mm = uTypedAlloc(ModMapEntry)((ModMapEntry *)uAlloc((unsigned)sizeof(ModMapEntry)));
696 if (mm == NULL((void*)0))
697 {
698 WSGOuInternalError("Could not allocate modifier map entry\n");
699 ACTION1uAction("Modifier map for %s will be incomplete\n",
700 XkbModIndexText(new->modifier, XkbMessage3));
701 return False0;
702 }
703 *mm = *new;
704 mm->defs.next = &info->modMap->defs;
705 info->modMap = mm;
706 return True1;
707}
708
709/***====================================================================***/
710
711static void
712MergeIncludedSymbols(SymbolsInfo * into, SymbolsInfo * from,
713 unsigned merge, XkbDescPtr xkb)
714{
715 register int i;
716 KeyInfo *key;
717
718 if (from->errorCount > 0)
719 {
720 into->errorCount += from->errorCount;
721 return;
722 }
723 if (into->name == NULL((void*)0))
724 {
725 into->name = from->name;
726 from->name = NULL((void*)0);
727 }
728 for (i = 0; i < XkbNumKbdGroups4; i++)
729 {
730 if (from->groupNames[i] != None0L)
731 {
732 if ((merge != MergeAugment1) || (into->groupNames[i] == None0L))
733 into->groupNames[i] = from->groupNames[i];
734 }
735 }
736 for (i = 0, key = from->keys; i < from->nKeys; i++, key++)
737 {
738 if (merge != MergeDefault0)
739 key->defs.merge = merge;
740 if (!AddKeySymbols(into, key, xkb))
741 into->errorCount++;
742 }
743 if (from->modMap != NULL((void*)0))
744 {
745 ModMapEntry *mm, *next;
746 for (mm = from->modMap; mm != NULL((void*)0); mm = next)
747 {
748 if (merge != MergeDefault0)
749 mm->defs.merge = merge;
750 if (!AddModMapEntry(into, mm))
751 into->errorCount++;
752 next = (ModMapEntry *) mm->defs.next;
753 uFree(mm);
754 }
755 from->modMap = NULL((void*)0);
756 }
757 if (!MergeAliases(&into->aliases, &from->aliases, merge))
758 into->errorCount++;
759 return;
760}
761
762typedef void (*FileHandler) (XkbFile * /* rtrn */ ,
763 XkbDescPtr /* xkb */ ,
764 unsigned /* merge */ ,
765 SymbolsInfo * /* included */
766 );
767
768static Boolint
769HandleIncludeSymbols(IncludeStmt * stmt,
770 XkbDescPtr xkb, SymbolsInfo * info, FileHandler hndlr)
771{
772 unsigned newMerge;
773 XkbFile *rtrn;
774 SymbolsInfo included;
775 Boolint haveSelf;
776
777 haveSelf = False0;
778 if ((stmt->file == NULL((void*)0)) && (stmt->map == NULL((void*)0)))
779 {
780 haveSelf = True1;
781 included = *info;
782 bzero(info, sizeof(SymbolsInfo))memset(info,0,sizeof(SymbolsInfo));
783 }
784 else if (ProcessIncludeFile(stmt, XkmSymbolsIndex2, &rtrn, &newMerge))
785 {
786 InitSymbolsInfo(&included, xkb);
787 included.fileID = included.dflt.defs.fileID = rtrn->id;
788 included.merge = included.dflt.defs.merge = MergeOverride2;
789 if (stmt->modifier)
790 {
791 included.explicit_group = atoi(stmt->modifier) - 1;
792 }
793 else
794 {
795 included.explicit_group = info->explicit_group;
796 }
797 (*hndlr) (rtrn, xkb, MergeOverride2, &included);
798 if (stmt->stmt != NULL((void*)0))
799 {
800 if (included.name != NULL((void*)0))
801 uFree(included.name);
802 included.name = stmt->stmt;
803 stmt->stmt = NULL((void*)0);
804 }
805 }
806 else
807 {
808 info->errorCount += 10;
809 return False0;
810 }
811 if ((stmt->next != NULL((void*)0)) && (included.errorCount < 1))
812 {
813 IncludeStmt *next;
814 unsigned op;
815 SymbolsInfo next_incl;
816
817 for (next = stmt->next; next != NULL((void*)0); next = next->next)
818 {
819 if ((next->file == NULL((void*)0)) && (next->map == NULL((void*)0)))
820 {
821 haveSelf = True1;
822 MergeIncludedSymbols(&included, info, next->merge, xkb);
823 FreeSymbolsInfo(info);
824 }
825 else if (ProcessIncludeFile(next, XkmSymbolsIndex2, &rtrn, &op))
826 {
827 InitSymbolsInfo(&next_incl, xkb);
828 next_incl.fileID = next_incl.dflt.defs.fileID = rtrn->id;
829 next_incl.merge = next_incl.dflt.defs.merge = MergeOverride2;
830 if (next->modifier)
831 {
832 next_incl.explicit_group = atoi(next->modifier) - 1;
833 }
834 else
835 {
836 next_incl.explicit_group = info->explicit_group;
837 }
838 (*hndlr) (rtrn, xkb, MergeOverride2, &next_incl);
839 MergeIncludedSymbols(&included, &next_incl, op, xkb);
840 FreeSymbolsInfo(&next_incl);
841 }
842 else
843 {
844 info->errorCount += 10;
845 return False0;
846 }
847 }
848 }
849 if (haveSelf)
850 *info = included;
851 else
852 {
853 MergeIncludedSymbols(info, &included, newMerge, xkb);
854 FreeSymbolsInfo(&included);
855 }
856 return (info->errorCount == 0);
857}
858
859static LookupEntry groupNames[] = {
860 {"group1", 1},
861 {"group2", 2},
862 {"group3", 3},
863 {"group4", 4},
864 {"group5", 5},
865 {"group6", 6},
866 {"group7", 7},
867 {"group8", 8},
868 {NULL((void*)0), 0}
869};
870
871
872#define SYMBOLS1 1
873#define ACTIONS2 2
874
875static Boolint
876GetGroupIndex(KeyInfo * key,
877 ExprDef * arrayNdx, unsigned what, unsigned *ndx_rtrn)
878{
879 const char *name;
880 ExprResult tmp;
881
882 if (what == SYMBOLS1)
883 name = "symbols";
884 else
885 name = "actions";
886
887 if (arrayNdx == NULL((void*)0))
888 {
889 register int i;
890 unsigned defined;
891 if (what == SYMBOLS1)
892 defined = key->symsDefined;
893 else
894 defined = key->actsDefined;
895
896 for (i = 0; i < XkbNumKbdGroups4; i++)
897 {
898 if ((defined & (1 << i)) == 0)
899 {
900 *ndx_rtrn = i;
901 return True1;
902 }
903 }
904 ERROR3uError("Too many groups of %s for key %s (max %d)\n", name,
905 longText(key->name, XkbMessage3), XkbNumKbdGroups4 + 1);
906 ACTION1uAction("Ignoring %s defined for extra groups\n", name);
907 return False0;
908 }
909 if (!ExprResolveInteger
910 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames))
911 {
912 ERROR2uError("Illegal group index for %s of key %s\n", name,
913 longText(key->name, XkbMessage3));
914 ACTIONuAction("Definition with non-integer array index ignored\n");
915 return False0;
916 }
917 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups4))
918 {
919 ERROR3uError("Group index for %s of key %s is out of range (1..%d)\n",
920 name, longText(key->name, XkbMessage3), XkbNumKbdGroups4 + 1);
921 ACTION2uAction("Ignoring %s for group %d\n", name, tmp.uval);
922 return False0;
923 }
924 *ndx_rtrn = tmp.uval - 1;
925 return True1;
926}
927
928static Boolint
929AddSymbolsToKey(KeyInfo * key,
930 XkbDescPtr xkb,
931 char *field,
932 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
933{
934 unsigned ndx, nSyms;
935 int i;
936
937 if (!GetGroupIndex(key, arrayNdx, SYMBOLS1, &ndx))
938 return False0;
939 if (value == NULL((void*)0))
940 {
941 key->symsDefined |= (1 << ndx);
942 return True1;
943 }
944 if (value->op != ExprKeysymList5)
945 {
946 ERROR1uError("Expected a list of symbols, found %s\n",
947 exprOpText(value->op));
948 ACTION2uAction("Ignoring symbols for group %d of %s\n", ndx,
949 longText(key->name, XkbMessage3));
950 return False0;
951 }
952 if (key->syms[ndx] != NULL((void*)0))
953 {
954 WSGO2uInternalError("Symbols for key %s, group %d already defined\n",
955 longText(key->name, XkbMessage3), ndx);
956 return False0;
957 }
958 nSyms = value->value.list.nSyms;
959 if (((key->numLevels[ndx] < nSyms) || (key->syms[ndx] == NULL((void*)0))) &&
960 (!ResizeKeyGroup(key, ndx, nSyms, False0)))
961 {
962 WSGO2uInternalError("Could not resize group %d of key %s\n", ndx,
963 longText(key->name, XkbMessage3));
964 ACTIONuAction("Symbols lost\n");
965 return False0;
966 }
967 key->symsDefined |= (1 << ndx);
968 for (i = 0; i < nSyms; i++) {
969 if (!LookupKeysym(value->value.list.syms[i], &key->syms[ndx][i])) {
970 WSGO1uInternalError("Could not resolve keysym %s\n", value->value.list.syms[i]);
971 key->syms[ndx][i] = NoSymbol0L;
972 }
973 }
974 for (i = key->numLevels[ndx] - 1;
975 (i >= 0) && (key->syms[ndx][i] == NoSymbol0L); i--)
976 {
977 key->numLevels[ndx]--;
978 }
979 return True1;
980}
981
982static Boolint
983AddActionsToKey(KeyInfo * key,
984 XkbDescPtr xkb,
985 char *field,
986 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
987{
988 register int i;
989 unsigned ndx, nActs;
990 ExprDef *act;
991 XkbAnyAction *toAct;
992
993 if (!GetGroupIndex(key, arrayNdx, ACTIONS2, &ndx))
994 return False0;
995
996 if (value == NULL((void*)0))
997 {
998 key->actsDefined |= (1 << ndx);
999 return True1;
1000 }
1001 if (value->op != ExprActionList6)
1002 {
1003 WSGO1uInternalError("Bad expression type (%d) for action list value\n", value->op);
1004 ACTION2uAction("Ignoring actions for group %d of %s\n", ndx,
1005 longText(key->name, XkbMessage3));
1006 return False0;
1007 }
1008 if (key->acts[ndx] != NULL((void*)0))
1009 {
1010 WSGO2uInternalError("Actions for key %s, group %d already defined\n",
1011 longText(key->name, XkbMessage3), ndx);
1012 return False0;
1013 }
1014 for (nActs = 0, act = value->value.child; act != NULL((void*)0); nActs++)
1015 {
1016 act = (ExprDef *) act->common.next;
1017 }
1018 if (nActs < 1)
1019 {
1020 WSGOuInternalError("Action list but not actions in AddActionsToKey\n");
1021 return False0;
1022 }
1023 if (((key->numLevels[ndx] < nActs) || (key->acts[ndx] == NULL((void*)0))) &&
1024 (!ResizeKeyGroup(key, ndx, nActs, True1)))
1025 {
1026 WSGO2uInternalError("Could not resize group %d of key %s\n", ndx,
1027 longText(key->name, XkbMessage3));
1028 ACTIONuAction("Actions lost\n");
1029 return False0;
1030 }
1031 key->actsDefined |= (1 << ndx);
1032
1033 toAct = (XkbAnyAction *) key->acts[ndx];
1034 act = value->value.child;
1035 for (i = 0; i < nActs; i++, toAct++)
1036 {
1037 if (!HandleActionDef(act, xkb, toAct, MergeOverride2, info->action))
1038 {
1039 ERROR1uError("Illegal action definition for %s\n",
1040 longText(key->name, XkbMessage3));
1041 ACTION2uAction("Action for group %d/level %d ignored\n", ndx + 1, i + 1);
1042 }
1043 act = (ExprDef *) act->common.next;
1044 }
1045 return True1;
1046}
1047
1048static int
1049SetAllowNone(KeyInfo * key, ExprDef * arrayNdx, ExprDef * value)
1050{
1051 ExprResult tmp;
1052 unsigned radio_groups = 0;
1053
1054 if (arrayNdx == NULL((void*)0))
1055 {
1056 radio_groups = XkbAllRadioGroupsMask(0xffffffff);
1057 }
1058 else
1059 {
1060 if (!ExprResolveInteger(arrayNdx, &tmp, RadioLookup, NULL((void*)0)))
1061 {
1062 ERRORuError("Illegal index in group name definition\n");
1063 ACTIONuAction("Definition with non-integer array index ignored\n");
1064 return False0;
1065 }
1066 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups32))
1067 {
1068 ERROR1uError("Illegal radio group specified (must be 1..%d)\n",
1069 XkbMaxRadioGroups32 + 1);
1070 ACTION1uAction("Value of \"allow none\" for group %d ignored\n",
1071 tmp.uval);
1072 return False0;
1073 }
1074 radio_groups |= (1 << (tmp.uval - 1));
1075 }
1076 if (!ExprResolveBoolean(value, &tmp, NULL((void*)0), NULL((void*)0)))
1077 {
1078 ERROR1uError("Illegal \"allow none\" value for %s\n",
1079 longText(key->name, XkbMessage3));
1080 ACTIONuAction("Non-boolean value ignored\n");
1081 return False0;
1082 }
1083 if (tmp.uval)
1084 key->allowNone |= radio_groups;
1085 else
1086 key->allowNone &= ~radio_groups;
1087 return True1;
1088}
1089
1090
1091static LookupEntry lockingEntries[] = {
1092 {"true", XkbKB_Lock0x01},
1093 {"yes", XkbKB_Lock0x01},
1094 {"on", XkbKB_Lock0x01},
1095 {"false", XkbKB_Default0x00},
1096 {"no", XkbKB_Default0x00},
1097 {"off", XkbKB_Default0x00},
1098 {"permanent", XkbKB_Lock0x01 | XkbKB_Permanent0x80},
1099 {NULL((void*)0), 0}
1100};
1101
1102static LookupEntry repeatEntries[] = {
1103 {"true", RepeatYes1},
1104 {"yes", RepeatYes1},
1105 {"on", RepeatYes1},
1106 {"false", RepeatNo0},
1107 {"no", RepeatNo0},
1108 {"off", RepeatNo0},
1109 {"default", RepeatUndefined~((unsigned)0)},
1110 {NULL((void*)0), 0}
1111};
1112
1113static LookupEntry rgEntries[] = {
1114 {"none", 0},
1115 {NULL((void*)0), 0}
1116};
1117
1118static Boolint
1119SetSymbolsField(KeyInfo * key,
1120 XkbDescPtr xkb,
1121 char *field,
1122 ExprDef * arrayNdx, ExprDef * value, SymbolsInfo * info)
1123{
1124 Boolint ok = True1;
1125 ExprResult tmp;
1126
1127 if (uStrCaseCmp(field, "type")(strcasecmp(field,"type")) == 0)
1128 {
1129 ExprResult ndx;
1130 if ((!ExprResolveString(value, &tmp, NULL((void*)0), NULL((void*)0)))
1131 && (warningLevel > 0))
1132 {
1133 WARNuWarning("The type field of a key symbol map must be a string\n");
1134 ACTIONuAction("Ignoring illegal type definition\n");
1135 }
1136 if (arrayNdx == NULL((void*)0))
1137 {
1138 key->dfltType = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1139 key->defs.defined |= _Key_Type_Dflt(1<<4);
1140 }
1141 else if (!ExprResolveInteger(arrayNdx, &ndx, SimpleLookup,
1142 (XPointer) groupNames))
1143 {
1144 ERROR1uError("Illegal group index for type of key %s\n",
1145 longText(key->name, XkbMessage3));
1146 ACTIONuAction("Definition with non-integer array index ignored\n");
1147 return False0;
1148 }
1149 else if ((ndx.uval < 1) || (ndx.uval > XkbNumKbdGroups4))
1150 {
1151 ERROR2uError
1152 ("Group index for type of key %s is out of range (1..%d)\n",
1153 longText(key->name, XkbMessage3), XkbNumKbdGroups4 + 1);
1154 ACTION1uAction("Ignoring type for group %d\n", ndx.uval);
1155 return False0;
1156 }
1157 else
1158 {
1159 key->types[ndx.uval - 1] = XkbInternAtom(NULL((void*)0), tmp.str, False0);
1160 key->typesDefined |= (1 << (ndx.uval - 1));
1161 }
1162 }
1163 else if (uStrCaseCmp(field, "symbols")(strcasecmp(field,"symbols")) == 0)
1164 return AddSymbolsToKey(key, xkb, field, arrayNdx, value, info);
1165 else if (uStrCaseCmp(field, "actions")(strcasecmp(field,"actions")) == 0)
1166 return AddActionsToKey(key, xkb, field, arrayNdx, value, info);
1167 else if ((uStrCaseCmp(field, "vmods")(strcasecmp(field,"vmods")) == 0) ||
1168 (uStrCaseCmp(field, "virtualmods")(strcasecmp(field,"virtualmods")) == 0) ||
1169 (uStrCaseCmp(field, "virtualmodifiers")(strcasecmp(field,"virtualmodifiers")) == 0))
1170 {
1171 ok = ExprResolveModMask(value, &tmp, LookupVModMask, (XPointer) xkb);
1172 if (ok)
1173 {
1174 key->vmodmap = (tmp.uval >> 8);
1175 key->defs.defined |= _Key_VModMap(1<<7);
1176 }
1177 else
1178 {
1179 ERROR1uError("Expected a virtual modifier mask, found %s\n",
1180 exprOpText(value->op));
1181 ACTION1uAction("Ignoring virtual modifiers definition for key %s\n",
1182 longText(key->name, XkbMessage3));
1183 }
1184 }
1185 else if ((uStrCaseCmp(field, "locking")(strcasecmp(field,"locking")) == 0)
1186 || (uStrCaseCmp(field, "lock")(strcasecmp(field,"lock")) == 0)
1187 || (uStrCaseCmp(field, "locks")(strcasecmp(field,"locks")) == 0))
1188 {
1189 ok = ExprResolveEnum(value, &tmp, lockingEntries);
1190 if (ok)
1191 key->behavior.type = tmp.uval;
1192 key->defs.defined |= _Key_Behavior(1<<3);
1193 }
1194 else if ((uStrCaseCmp(field, "radiogroup")(strcasecmp(field,"radiogroup")) == 0) ||
1195 (uStrCaseCmp(field, "permanentradiogroup")(strcasecmp(field,"permanentradiogroup")) == 0))
1196 {
1197 Boolint permanent = False0;
1198 if (uStrCaseCmp(field, "permanentradiogroup")(strcasecmp(field,"permanentradiogroup")) == 0)
1199 permanent = True1;
1200 ok = ExprResolveInteger(value, &tmp, SimpleLookup,
1201 (XPointer) rgEntries);
1202 if (!ok)
1203 {
1204 ERROR1uError("Illegal radio group specification for %s\n",
1205 longText(key->name, XkbMessage3));
1206 ACTIONuAction("Non-integer radio group ignored\n");
1207 return False0;
1208 }
1209 if (tmp.uval == 0)
1210 {
1211 key->behavior.type = XkbKB_Default0x00;
1212 key->behavior.data = 0;
1213 return ok;
1214 }
1215 if ((tmp.uval < 1) || (tmp.uval > XkbMaxRadioGroups32))
1216 {
1217 ERROR1uError
1218 ("Radio group specification for %s out of range (1..32)\n",
1219 longText(key->name, XkbMessage3));
1220 ACTION1uAction("Illegal radio group %d ignored\n", tmp.uval);
1221 return False0;
1222 }
1223 key->behavior.type =
1224 XkbKB_RadioGroup0x02 | (permanent ? XkbKB_Permanent0x80 : 0);
1225 key->behavior.data = tmp.uval - 1;
1226 if (key->allowNone & (1 << (tmp.uval - 1)))
1227 key->behavior.data |= XkbKB_RGAllowNone0x80;
1228 key->defs.defined |= _Key_Behavior(1<<3);
1229 }
1230 else if (uStrCaseEqual(field, "allownone")((strcasecmp(field,"allownone"))==0))
1231 {
1232 ok = SetAllowNone(key, arrayNdx, value);
1233 }
1234 else if (uStrCasePrefix("overlay", field)(strncasecmp("overlay",field,strlen("overlay"))==0) ||
1235 uStrCasePrefix("permanentoverlay", field)(strncasecmp("permanentoverlay",field,strlen("permanentoverlay"
))==0)
)
1236 {
1237 Boolint permanent = False0;
1238 char *which;
1239 int overlayNdx;
1240 if (uStrCasePrefix("permanent", field)(strncasecmp("permanent",field,strlen("permanent"))==0))
1241 {
1242 permanent = True1;
1243 which = &field[sizeof("permanentoverlay") - 1];
1244 }
1245 else
1246 {
1247 which = &field[sizeof("overlay") - 1];
1248 }
1249 if (sscanf(which, "%d", &overlayNdx) == 1)
1250 {
1251 if (((overlayNdx < 1) || (overlayNdx > 2)) && (warningLevel > 0))
1252 {
1253 ERROR2uError("Illegal overlay %d specified for %s\n",
1254 overlayNdx, longText(key->name, XkbMessage3));
1255 ACTIONuAction("Ignored\n");
1256 return False0;
1257 }
1258 }
1259 else if (*which == '\0')
1260 overlayNdx = 1;
1261 else if (warningLevel > 0)
1262 {
1263 ERROR2uError("Illegal overlay \"%s\" specified for %s\n",
1264 which, longText(key->name, XkbMessage3));
1265 ACTIONuAction("Ignored\n");
1266 return False0;
1267 }
1268 ok = ExprResolveKeyName(value, &tmp, NULL((void*)0), NULL((void*)0));
1269 if (!ok)
1270 {
1271 ERROR1uError("Illegal overlay key specification for %s\n",
1272 longText(key->name, XkbMessage3));
1273 ACTIONuAction("Overlay key must be specified by name\n");
1274 return False0;
1275 }
1276 if (overlayNdx == 1)
1277 key->behavior.type = XkbKB_Overlay10x03;
1278 else
1279 key->behavior.type = XkbKB_Overlay20x04;
1280 if (permanent)
1281 key->behavior.type |= XkbKB_Permanent0x80;
1282
1283 key->behavior.data = 0;
1284 key->nameForOverlayKey = KeyNameToLong(tmp.keyName.name)((((unsigned long)tmp.keyName.name[0])<<24)|(((unsigned
long)tmp.keyName.name[1])<<16)|(((unsigned long)tmp.keyName
.name[2])<<8)|tmp.keyName.name[3])
;
1285 key->defs.defined |= _Key_Behavior(1<<3);
1286 }
1287 else if ((uStrCaseCmp(field, "repeating")(strcasecmp(field,"repeating")) == 0) ||
1288 (uStrCaseCmp(field, "repeats")(strcasecmp(field,"repeats")) == 0) ||
1289 (uStrCaseCmp(field, "repeat")(strcasecmp(field,"repeat")) == 0))
1290 {
1291 ok = ExprResolveEnum(value, &tmp, repeatEntries);
1292 if (!ok)
1293 {
1294 ERROR1uError("Illegal repeat setting for %s\n",
1295 longText(key->name, XkbMessage3));
1296 ACTIONuAction("Non-boolean repeat setting ignored\n");
1297 return False0;
1298 }
1299 key->repeat = tmp.uval;
1300 key->defs.defined |= _Key_Repeat(1<<2);
1301 }
1302 else if ((uStrCaseCmp(field, "groupswrap")(strcasecmp(field,"groupswrap")) == 0) ||
1303 (uStrCaseCmp(field, "wrapgroups")(strcasecmp(field,"wrapgroups")) == 0))
1304 {
1305 ok = ExprResolveBoolean(value, &tmp, NULL((void*)0), NULL((void*)0));
1306 if (!ok)
1307 {
1308 ERROR1uError("Illegal groupsWrap setting for %s\n",
1309 longText(key->name, XkbMessage3));
1310 ACTIONuAction("Non-boolean value ignored\n");
1311 return False0;
1312 }
1313 if (tmp.uval)
1314 key->groupInfo = XkbWrapIntoRange(0x00);
1315 else
1316 key->groupInfo = XkbClampIntoRange(0x40);
1317 key->defs.defined |= _Key_GroupInfo(1<<6);
1318 }
1319 else if ((uStrCaseCmp(field, "groupsclamp")(strcasecmp(field,"groupsclamp")) == 0) ||
1320 (uStrCaseCmp(field, "clampgroups")(strcasecmp(field,"clampgroups")) == 0))
1321 {
1322 ok = ExprResolveBoolean(value, &tmp, NULL((void*)0), NULL((void*)0));
1323 if (!ok)
1324 {
1325 ERROR1uError("Illegal groupsClamp setting for %s\n",
1326 longText(key->name, XkbMessage3));
1327 ACTIONuAction("Non-boolean value ignored\n");
1328 return False0;
1329 }
1330 if (tmp.uval)
1331 key->groupInfo = XkbClampIntoRange(0x40);
1332 else
1333 key->groupInfo = XkbWrapIntoRange(0x00);
1334 key->defs.defined |= _Key_GroupInfo(1<<6);
1335 }
1336 else if ((uStrCaseCmp(field, "groupsredirect")(strcasecmp(field,"groupsredirect")) == 0) ||
1337 (uStrCaseCmp(field, "redirectgroups")(strcasecmp(field,"redirectgroups")) == 0))
1338 {
1339 if (!ExprResolveInteger
1340 (value, &tmp, SimpleLookup, (XPointer) groupNames))
1341 {
1342 ERROR1uError("Illegal group index for redirect of key %s\n",
1343 longText(key->name, XkbMessage3));
1344 ACTIONuAction("Definition with non-integer group ignored\n");
1345 return False0;
1346 }
1347 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups4))
1348 {
1349 ERROR2uError("Out-of-range (1..%d) group for redirect of key %s\n",
1350 XkbNumKbdGroups4, longText(key->name, XkbMessage3));
1351 ERROR1uError("Ignoring illegal group %d\n", tmp.uval);
1352 return False0;
1353 }
1354 key->groupInfo =
1355 XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval - 1)((((0x80))&0xc0)|(((tmp.uval - 1)&3)<<4)|((0)&
0x0f))
;
1356 key->defs.defined |= _Key_GroupInfo(1<<6);
1357 }
1358 else
1359 {
1360 ERROR1uError("Unknown field %s in a symbol interpretation\n", field);
1361 ACTIONuAction("Definition ignored\n");
1362 ok = False0;
1363 }
1364 return ok;
1365}
1366
1367static int
1368SetGroupName(SymbolsInfo * info, ExprDef * arrayNdx, ExprDef * value)
1369{
1370 ExprResult tmp, name;
1371
1372 if ((arrayNdx == NULL((void*)0)) && (warningLevel > 0))
1373 {
1374 WARNuWarning("You must specify an index when specifying a group name\n");
1375 ACTIONuAction("Group name definition without array subscript ignored\n");
1376 return False0;
1377 }
1378 if (!ExprResolveInteger
1379 (arrayNdx, &tmp, SimpleLookup, (XPointer) groupNames))
1380 {
1381 ERRORuError("Illegal index in group name definition\n");
1382 ACTIONuAction("Definition with non-integer array index ignored\n");
1383 return False0;
1384 }
1385 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups4))
1386 {
1387 ERROR1uError
1388 ("Attempt to specify name for illegal group (must be 1..%d)\n",
1389 XkbNumKbdGroups4 + 1);
1390 ACTION1uAction("Name for group %d ignored\n", tmp.uval);
1391 return False0;
1392 }
1393 if (!ExprResolveString(value, &name, NULL((void*)0), NULL((void*)0)))
1394 {
1395 ERRORuError("Group name must be a string\n");
1396 ACTION1uAction("Illegal name for group %d ignored\n", tmp.uval);
1397 return False0;
1398 }
1399 info->groupNames[tmp.uval - 1 + info->explicit_group] =
1400 XkbInternAtom(NULL((void*)0), name.str, False0);
1401
1402 return True1;
1403}
1404
1405static int
1406HandleSymbolsVar(VarDef * stmt, XkbDescPtr xkb, SymbolsInfo * info)
1407{
1408 ExprResult elem, field, tmp;
1409 ExprDef *arrayNdx;
1410
1411 if (ExprResolveLhs(stmt->name, &elem, &field, &arrayNdx) == 0)
1412 return 0; /* internal error, already reported */
1413 if (elem.str && (uStrCaseCmp(elem.str, "key")(strcasecmp(elem.str,"key")) == 0))
1414 {
1415 return SetSymbolsField(&info->dflt, xkb, field.str, arrayNdx,
1416 stmt->value, info);
1417 }
1418 else if ((elem.str == NULL((void*)0)) && ((uStrCaseCmp(field.str, "name")(strcasecmp(field.str,"name")) == 0) ||
1419 (uStrCaseCmp(field.str, "groupname")(strcasecmp(field.str,"groupname")) ==
1420 0)))
1421 {
1422 return SetGroupName(info, arrayNdx, stmt->value);
1423 }
1424 else if ((elem.str == NULL((void*)0))
1425 && ((uStrCaseCmp(field.str, "groupswrap")(strcasecmp(field.str,"groupswrap")) == 0)
1426 || (uStrCaseCmp(field.str, "wrapgroups")(strcasecmp(field.str,"wrapgroups")) == 0)))
1427 {
1428 if (!ExprResolveBoolean(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
1429 {
1430 ERRORuError("Illegal setting for global groupsWrap\n");
1431 ACTIONuAction("Non-boolean value ignored\n");
1432 return False0;
1433 }
1434 if (tmp.uval)
1435 info->groupInfo = XkbWrapIntoRange(0x00);
1436 else
1437 info->groupInfo = XkbClampIntoRange(0x40);
1438 return True1;
1439 }
1440 else if ((elem.str == NULL((void*)0))
1441 && ((uStrCaseCmp(field.str, "groupsclamp")(strcasecmp(field.str,"groupsclamp")) == 0)
1442 || (uStrCaseCmp(field.str, "clampgroups")(strcasecmp(field.str,"clampgroups")) == 0)))
1443 {
1444 if (!ExprResolveBoolean(stmt->value, &tmp, NULL((void*)0), NULL((void*)0)))
1445 {
1446 ERRORuError("Illegal setting for global groupsClamp\n");
1447 ACTIONuAction("Non-boolean value ignored\n");
1448 return False0;
1449 }
1450 if (tmp.uval)
1451 info->groupInfo = XkbClampIntoRange(0x40);
1452 else
1453 info->groupInfo = XkbWrapIntoRange(0x00);
1454 return True1;
1455 }
1456 else if ((elem.str == NULL((void*)0))
1457 && ((uStrCaseCmp(field.str, "groupsredirect")(strcasecmp(field.str,"groupsredirect")) == 0)
1458 || (uStrCaseCmp(field.str, "redirectgroups")(strcasecmp(field.str,"redirectgroups")) == 0)))
1459 {
1460 if (!ExprResolveInteger(stmt->value, &tmp,
1461 SimpleLookup, (XPointer) groupNames))
1462 {
1463 ERRORuError("Illegal group index for global groupsRedirect\n");
1464 ACTIONuAction("Definition with non-integer group ignored\n");
1465 return False0;
1466 }
1467 if ((tmp.uval < 1) || (tmp.uval > XkbNumKbdGroups4))
1468 {
1469 ERROR1uError
1470 ("Out-of-range (1..%d) group for global groupsRedirect\n",
1471 XkbNumKbdGroups4);
1472 ACTION1uAction("Ignoring illegal group %d\n", tmp.uval);
1473 return False0;
1474 }
1475 info->groupInfo = XkbSetGroupInfo(0, XkbRedirectIntoRange, tmp.uval)((((0x80))&0xc0)|(((tmp.uval)&3)<<4)|((0)&0x0f
))
;
1476 return True1;
1477 }
1478 else if ((elem.str == NULL((void*)0)) && (uStrCaseCmp(field.str, "allownone")(strcasecmp(field.str,"allownone")) == 0))
1479 {
1480 return SetAllowNone(&info->dflt, arrayNdx, stmt->value);
1481 }
1482 return SetActionField(xkb, elem.str, field.str, arrayNdx, stmt->value,
1483 &info->action);
1484}
1485
1486static Boolint
1487HandleSymbolsBody(VarDef * def,
1488 XkbDescPtr xkb, KeyInfo * key, SymbolsInfo * info)
1489{
1490 Boolint ok = True1;
1491 ExprResult tmp, field;
1492 ExprDef *arrayNdx;
1493
1494 for (; def != NULL((void*)0); def = (VarDef *) def->common.next)
1495 {
1496 if ((def->name) && (def->name->type == ExprFieldRef3))
1497 {
1498 ok = HandleSymbolsVar(def, xkb, info);
1499 continue;
1500 }
1501 else
1502 {
1503 if (def->name == NULL((void*)0))
1504 {
1505 if ((def->value == NULL((void*)0))
1506 || (def->value->op == ExprKeysymList5))
1507 field.str = "symbols";
1508 else
1509 field.str = "actions";
1510 arrayNdx = NULL((void*)0);
1511 }
1512 else
1513 {
1514 ok = ExprResolveLhs(def->name, &tmp, &field, &arrayNdx);
1515 }
1516 if (ok)
1517 ok = SetSymbolsField(key, xkb, field.str, arrayNdx,
1518 def->value, info);
1519 }
1520 }
1521 return ok;
1522}
1523
1524static Boolint
1525SetExplicitGroup(SymbolsInfo * info, KeyInfo * key)
1526{
1527 unsigned group = info->explicit_group;
1528
1529 if (group == 0)
1530 return True1;
1531
1532 if ((key->typesDefined | key->symsDefined | key->actsDefined) & ~1)
1533 {
1534 int i;
1535 WARN1uWarning("For the map %s an explicit group specified\n", info->name);
1536 WARN1uWarning("but key %s has more than one group defined\n",
1537 longText(key->name, XkbMessage3));
1538 ACTIONuAction("All groups except first one will be ignored\n");
1539 for (i = 1; i < XkbNumKbdGroups4; i++)
1540 {
1541 key->numLevels[i] = 0;
1542 if (key->syms[i] != NULL((void*)0))
1543 uFree(key->syms[i]);
1544 key->syms[i] = (KeySym *) NULL((void*)0);
1545 if (key->acts[i] != NULL((void*)0))
1546 uFree(key->acts[i]);
1547 key->acts[i] = (XkbAction *) NULL((void*)0);
1548 key->types[i] = (Atom) 0;
1549 }
1550 }
1551 key->typesDefined = key->symsDefined = key->actsDefined = 1 << group;
1552
1553 key->numLevels[group] = key->numLevels[0];
1554 key->numLevels[0] = 0;
1555 key->syms[group] = key->syms[0];
1556 key->syms[0] = (KeySym *) NULL((void*)0);
1557 key->acts[group] = key->acts[0];
1558 key->acts[0] = (XkbAction *) NULL((void*)0);
1559 key->types[group] = key->types[0];
1560 key->types[0] = (Atom) 0;
1561 return True1;
1562}
1563
1564static int
1565HandleSymbolsDef(SymbolsDef * stmt,
1566 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1567{
1568 KeyInfo key;
1569
1570 InitKeyInfo(&key);
1571 CopyKeyInfo(&info->dflt, &key, False0);
1572 key.defs.merge = stmt->merge;
1573 key.name = KeyNameToLong(stmt->keyName)((((unsigned long)stmt->keyName[0])<<24)|(((unsigned
long)stmt->keyName[1])<<16)|(((unsigned long)stmt->
keyName[2])<<8)|stmt->keyName[3])
;
1574 if (!HandleSymbolsBody((VarDef *) stmt->symbols, xkb, &key, info))
1575 {
1576 info->errorCount++;
1577 return False0;
1578 }
1579
1580 if (!SetExplicitGroup(info, &key))
1581 {
1582 info->errorCount++;
1583 return False0;
1584 }
1585
1586 if (!AddKeySymbols(info, &key, xkb))
1587 {
1588 info->errorCount++;
1589 return False0;
1590 }
1591 return True1;
1592}
1593
1594static Boolint
1595HandleModMapDef(ModMapDef * def,
1596 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1597{
1598 ExprDef *key;
1599 ModMapEntry tmp;
1600 ExprResult rtrn;
1601 Boolint ok;
1602
1603 if (!LookupModIndex(NULL((void*)0), None0L, def->modifier, TypeInt2, &rtrn))
1604 {
1605 ERRORuError("Illegal modifier map definition\n");
1606 ACTION1uAction("Ignoring map for non-modifier \"%s\"\n",
1607 XkbAtomText(NULL((void*)0), def->modifier, XkbMessage3));
1608 return False0;
1609 }
1610 ok = True1;
1611 tmp.modifier = rtrn.uval;
1612 for (key = def->keys; key != NULL((void*)0); key = (ExprDef *) key->common.next)
1613 {
1614 if ((key->op == ExprValue0) && (key->type == TypeKeyName6))
1615 {
1616 tmp.haveSymbol = False0;
1617 tmp.u.keyName = KeyNameToLong(key->value.keyName)((((unsigned long)key->value.keyName[0])<<24)|(((unsigned
long)key->value.keyName[1])<<16)|(((unsigned long)key
->value.keyName[2])<<8)|key->value.keyName[3])
;
1618 }
1619 else if (ExprResolveKeySym(key, &rtrn, NULL((void*)0), NULL((void*)0)))
1620 {
1621 tmp.haveSymbol = True1;
1622 tmp.u.keySym = rtrn.uval;
1623 }
1624 else
1625 {
1626 ERRORuError("Modmap entries may contain only key names or keysyms\n");
1627 ACTION1uAction("Illegal definition for %s modifier ignored\n",
1628 XkbModIndexText(tmp.modifier, XkbMessage3));
1629 continue;
1630 }
1631
1632 ok = AddModMapEntry(info, &tmp) && ok;
1633 }
1634 return ok;
1635}
1636
1637static void
1638HandleSymbolsFile(XkbFile * file,
1639 XkbDescPtr xkb, unsigned merge, SymbolsInfo * info)
1640{
1641 ParseCommon *stmt;
1642
1643 info->name = uStringDup(file->name)((file->name) ? strdup(file->name) : ((void*)0));
1644 stmt = file->defs;
1645 while (stmt)
1646 {
1647 switch (stmt->stmtType)
1648 {
1649 case StmtInclude1:
1650 if (!HandleIncludeSymbols((IncludeStmt *) stmt, xkb, info,
1651 HandleSymbolsFile))
1652 info->errorCount++;
1653 break;
1654 case StmtSymbolsDef9:
1655 if (!HandleSymbolsDef((SymbolsDef *) stmt, xkb, merge, info))
1656 info->errorCount++;
1657 break;
1658 case StmtVarDef5:
1659 if (!HandleSymbolsVar((VarDef *) stmt, xkb, info))
1660 info->errorCount++;
1661 break;
1662 case StmtVModDef8:
1663 if (!HandleVModDef((VModDef *) stmt, merge, &info->vmods))
1664 info->errorCount++;
1665 break;
1666 case StmtInterpDef7:
1667 ERRORuError("Interpretation files may not include other types\n");
1668 ACTIONuAction("Ignoring definition of symbol interpretation\n");
1669 info->errorCount++;
1670 break;
1671 case StmtKeycodeDef2:
1672 ERRORuError("Interpretation files may not include other types\n");
1673 ACTIONuAction("Ignoring definition of key name\n");
1674 info->errorCount++;
1675 break;
1676 case StmtModMapDef10:
1677 if (!HandleModMapDef((ModMapDef *) stmt, xkb, merge, info))
1678 info->errorCount++;
1679 break;
1680 default:
1681 WSGO1uInternalError("Unexpected statement type %d in HandleSymbolsFile\n",
1682 stmt->stmtType);
1683 break;
1684 }
1685 stmt = stmt->next;
1686 if (info->errorCount > 10)
1687 {
1688#ifdef NOISY
1689 ERRORuError("Too many errors\n");
1690#endif
1691 ACTION1uAction("Abandoning symbols file \"%s\"\n", file->topName);
1692 break;
1693 }
1694 }
1695 return;
1696}
1697
1698static Boolint
1699FindKeyForSymbol(XkbDescPtr xkb, KeySym sym, unsigned int *kc_rtrn)
1700{
1701 register int i, j;
1702 register Boolint gotOne;
1703
1704 j = 0;
1705 do
1706 {
1707 gotOne = False0;
1708 for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++)
1709 {
1710 if (j < (int) XkbKeyNumSyms(xkb, i)(((((xkb)->map)->key_sym_map[(i)].width)*(((((xkb)->
map)->key_sym_map[(i)].group_info)&0x0f))))
)
1711 {
1712 gotOne = True1;
1713 if (XkbKeySym(xkb, i, j)(((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map
[(i)].offset)]))[j])
== sym)
1714 {
1715 *kc_rtrn = i;
1716 return True1;
1717 }
1718 }
1719 }
1720 j++;
1721 }
1722 while (gotOne);
1723 return False0;
1724}
1725
1726/**
1727 * Find the given name in the xkb->map->types and return its index.
1728 *
1729 * @param name The atom to search for.
1730 * @param type_rtrn Set to the index of the name if found.
1731 *
1732 * @return True if found, False otherwise.
1733 */
1734static Boolint
1735FindNamedType(XkbDescPtr xkb, Atom name, unsigned *type_rtrn)
1736{
1737 register unsigned n;
1738
1739 if (xkb && xkb->map && xkb->map->types)
1740 {
1741 for (n = 0; n < xkb->map->num_types; n++)
1742 {
1743 if (xkb->map->types[n].name == (Atom) name)
1744 {
1745 *type_rtrn = n;
1746 return True1;
1747 }
1748 }
1749 }
1750 return False0;
1751}
1752
1753static Boolint
1754KSIsLower(KeySym ks)
1755{
1756 KeySym lower, upper;
1757 XConvertCase(ks, &lower, &upper);
1758
1759 if (lower == upper)
1760 return False0;
1761 return (ks == lower ? True1 : False0);
1762}
1763
1764static Boolint
1765KSIsUpper(KeySym ks)
1766{
1767 KeySym lower, upper;
1768 XConvertCase(ks, &lower, &upper);
1769
1770 if (lower == upper)
1771 return False0;
1772 return (ks == upper ? True1 : False0);
1773}
1774
1775/**
1776 * Assign a type to the given sym and return the Atom for the type assigned.
1777 *
1778 * Simple recipe:
1779 * - ONE_LEVEL for width 0/1
1780 * - ALPHABETIC for 2 shift levels, with lower/upercase
1781 * - KEYPAD for keypad keys.
1782 * - TWO_LEVEL for other 2 shift level keys.
1783 * and the same for four level keys.
1784 *
1785 * @param width Number of sysms in syms.
1786 * @param syms The keysyms for the given key (must be size width).
1787 * @param typeNameRtrn Set to the Atom of the type name.
1788 *
1789 * @returns True if a type could be found, False otherwise.
1790 */
1791static Boolint
1792FindAutomaticType(int width, KeySym * syms, Atom * typeNameRtrn,
1793 Boolint * autoType)
1794{
1795 *autoType = False0;
1796 if ((width == 1) || (width == 0))
1797 {
1798 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "ONE_LEVEL", False0);
1799 *autoType = True1;
1800 }
1801 else if (width == 2)
1802 {
1803 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1804 {
1805 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "ALPHABETIC", False0);
1806 }
1807 else if (syms && (XkbKSIsKeypad(syms[0])(((syms[0])>=0xff80)&&((syms[0])<=0xffbd)) || XkbKSIsKeypad(syms[1])(((syms[1])>=0xff80)&&((syms[1])<=0xffbd))))
1808 {
1809 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "KEYPAD", False0);
1810 *autoType = True1;
1811 }
1812 else
1813 {
1814 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "TWO_LEVEL", False0);
1815 *autoType = True1;
1816 }
1817 }
1818 else if (width <= 4)
1819 {
1820 if (syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]))
1821 if (KSIsLower(syms[2]) && KSIsUpper(syms[3]))
1822 *typeNameRtrn =
1823 XkbInternAtom(NULL((void*)0), "FOUR_LEVEL_ALPHABETIC", False0);
1824 else
1825 *typeNameRtrn = XkbInternAtom(NULL((void*)0),
1826 "FOUR_LEVEL_SEMIALPHABETIC",
1827 False0);
1828
1829 else if (syms && (XkbKSIsKeypad(syms[0])(((syms[0])>=0xff80)&&((syms[0])<=0xffbd)) || XkbKSIsKeypad(syms[1])(((syms[1])>=0xff80)&&((syms[1])<=0xffbd))))
1830 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "FOUR_LEVEL_KEYPAD", False0);
1831 else
1832 *typeNameRtrn = XkbInternAtom(NULL((void*)0), "FOUR_LEVEL", False0);
1833 /* XXX: why not set autoType here? */
1834 }
1835 return ((width >= 0) && (width <= 4));
1836}
1837
1838/**
1839 * Ensure the given KeyInfo is in a coherent state, i.e. no gaps between the
1840 * groups, and reduce to one group if all groups are identical anyway.
1841 */
1842static void
1843PrepareKeyDef(KeyInfo * key)
1844{
1845 int i, j, width, defined, lastGroup;
1846 Boolint identical;
1847
1848 defined = key->symsDefined | key->actsDefined | key->typesDefined;
1849 /* get highest group number */
1850 for (i = XkbNumKbdGroups4 - 1; i >= 0; i--)
1851 {
1852 if (defined & (1 << i))
1853 break;
1854 }
1855 lastGroup = i;
1856
1857 if (lastGroup == 0)
1858 return;
1859
1860 /* If there are empty groups between non-empty ones fill them with data */
1861 /* from the first group. */
1862 /* We can make a wrong assumption here. But leaving gaps is worse. */
1863 for (i = lastGroup; i > 0; i--)
1864 {
1865 if (defined & (1 << i))
1866 continue;
1867 width = key->numLevels[0];
1868 if (key->typesDefined & 1)
1869 {
1870 for (j = 0; j < width; j++)
1871 {
1872 key->types[i] = key->types[0];
1873 }
1874 key->typesDefined |= 1 << i;
1875 }
1876 if ((key->actsDefined & 1) && key->acts[0])
1877 {
1878 key->acts[i] = uTypedCalloc(width, XkbAction)((XkbAction *)uCalloc((unsigned)width,(unsigned)sizeof(XkbAction
)))
;
1879 if (key->acts[i] == NULL((void*)0))
1880 continue;
1881 memcpy((void *) key->acts[i], (void *) key->acts[0],
1882 width * sizeof(XkbAction));
1883 key->actsDefined |= 1 << i;
1884 }
1885 if ((key->symsDefined & 1) && key->syms[0])
1886 {
1887 key->syms[i] = uTypedCalloc(width, KeySym)((KeySym *)uCalloc((unsigned)width,(unsigned)sizeof(KeySym)));
1888 if (key->syms[i] == NULL((void*)0))
1889 continue;
1890 memcpy((void *) key->syms[i], (void *) key->syms[0],
1891 width * sizeof(KeySym));
1892 key->symsDefined |= 1 << i;
1893 }
1894 if (defined & 1)
1895 {
1896 key->numLevels[i] = key->numLevels[0];
1897 }
1898 }
1899 /* If all groups are completely identical remove them all */
1900 /* exept the first one. */
1901 identical = True1;
1902 for (i = lastGroup; i > 0; i--)
1903 {
1904 if ((key->numLevels[i] != key->numLevels[0]) ||
1905 (key->types[i] != key->types[0]))
1906 {
1907 identical = False0;
1908 break;
1909 }
1910 if ((key->syms[i] != key->syms[0]) &&
1911 (key->syms[i] == NULL((void*)0) || key->syms[0] == NULL((void*)0) ||
1912 memcmp((void *) key->syms[i], (void *) key->syms[0],
1913 sizeof(KeySym) * key->numLevels[0])))
1914 {
1915 identical = False0;
1916 break;
1917 }
1918 if ((key->acts[i] != key->acts[0]) &&
1919 (key->acts[i] == NULL((void*)0) || key->acts[0] == NULL((void*)0) ||
1920 memcmp((void *) key->acts[i], (void *) key->acts[0],
1921 sizeof(XkbAction) * key->numLevels[0])))
1922 {
1923 identical = False0;
1924 break;
1925 }
1926 }
1927 if (identical)
1928 {
1929 for (i = lastGroup; i > 0; i--)
1930 {
1931 key->numLevels[i] = 0;
1932 if (key->syms[i] != NULL((void*)0))
1933 uFree(key->syms[i]);
1934 key->syms[i] = (KeySym *) NULL((void*)0);
1935 if (key->acts[i] != NULL((void*)0))
1936 uFree(key->acts[i]);
1937 key->acts[i] = (XkbAction *) NULL((void*)0);
1938 key->types[i] = (Atom) 0;
1939 }
1940 key->symsDefined &= 1;
1941 key->actsDefined &= 1;
1942 key->typesDefined &= 1;
1943 }
1944 return;
1945}
1946
1947/**
1948 * Copy the KeyInfo into result.
1949 *
1950 * This function recurses.
1951 */
1952static Boolint
1953CopySymbolsDef(XkbFileInfo * result, KeyInfo * key, int start_from)
1954{
1955 register int i;
1956 unsigned okc, kc, width, tmp, nGroups;
1957 XkbKeyTypePtr type;
1958 Boolint haveActions, autoType, useAlias;
1959 KeySym *outSyms;
1960 XkbAction *outActs;
1961 XkbDescPtr xkb;
1962 unsigned types[XkbNumKbdGroups4];
1963
1964 xkb = result->xkb;
1965 useAlias = (start_from == 0);
1966
1967 /* get the keycode for the key. */
1968 if (!FindNamedKey(xkb, key->name, &kc, useAlias, CreateKeyNames(xkb)((xkb)->flags&(1L << 0)),
1969 start_from))
1970 {
1971 if ((start_from == 0) && (warningLevel >= 5))
1972 {
1973 WARN2uWarning("Key %s not found in %s keycodes\n",
1974 longText(key->name, XkbMessage3),
1975 XkbAtomText(NULL((void*)0), xkb->names->keycodes, XkbMessage3));
1976 ACTIONuAction("Symbols ignored\n");
1977 }
1978 return False0;
1979 }
1980
1981 haveActions = False0;
1982 for (i = width = nGroups = 0; i < XkbNumKbdGroups4; i++)
1983 {
1984 if (((i + 1) > nGroups)
1985 && (((key->symsDefined | key->actsDefined) & (1 << i))
1986 || (key->typesDefined) & (1 << i)))
1987 nGroups = i + 1;
1988 if (key->acts[i])
1989 haveActions = True1;
1990 autoType = False0;
1991 /* Assign the type to the key, if it is missing. */
1992 if (key->types[i] == None0L)
1993 {
1994 if (key->dfltType != None0L)
1995 key->types[i] = key->dfltType;
1996 else if (FindAutomaticType(key->numLevels[i], key->syms[i],
1997 &key->types[i], &autoType))
1998 {
1999 }
2000 else
2001 {
2002 if (warningLevel >= 5)
2003 {
2004 WARN1uWarning("No automatic type for %d symbols\n",
2005 (unsigned int) key->numLevels[i]);
2006 ACTION3uAction("Using %s for the %s key (keycode %d)\n",
2007 XkbAtomText(NULL((void*)0), key->types[i],
2008 XkbMessage3),
2009 longText(key->name, XkbMessage3), kc);
2010 }
2011 }
2012 }
2013 if (FindNamedType(xkb, key->types[i], &types[i]))
2014 {
2015 if (!autoType || key->numLevels[i] > 2)
2016 xkb->server->explicit[kc] |= (1 << i);
2017 }
2018 else
2019 {
2020 if (warningLevel >= 3)
2021 {
2022 WARN1uWarning("Type \"%s\" is not defined\n",
2023 XkbAtomText(NULL((void*)0), key->types[i], XkbMessage3));
2024 ACTION2uAction("Using TWO_LEVEL for the %s key (keycode %d)\n",
2025 longText(key->name, XkbMessage3), kc);
2026 }
2027 types[i] = XkbTwoLevelIndex1;
2028 }
2029 /* if the type specifies less syms than the key has, shrink the key */
2030 type = &xkb->map->types[types[i]];
2031 if (type->num_levels < key->numLevels[i])
2032 {
2033 if (warningLevel > 0)
2034 {
2035 WARN4uWarning
2036 ("Type \"%s\" has %d levels, but %s has %d symbols\n",
2037 XkbAtomText(NULL((void*)0), type->name, XkbMessage3),
2038 (unsigned int) type->num_levels,
2039 longText(key->name, XkbMessage3),
2040 (unsigned int) key->numLevels[i]);
2041 ACTIONuAction("Ignoring extra symbols\n");
2042 }
2043 key->numLevels[i] = type->num_levels;
2044 }
2045 if (key->numLevels[i] > width)
2046 width = key->numLevels[i];
2047 if (type->num_levels > width)
2048 width = type->num_levels;
2049 }
2050
2051 /* width is now the largest width found */
2052
2053 i = width * nGroups;
2054 outSyms = XkbResizeKeySyms(xkb, kc, i);
2055 if (outSyms == NULL((void*)0))
2056 {
2057 WSGO2uInternalError("Could not enlarge symbols for %s (keycode %d)\n",
2058 longText(key->name, XkbMessage3), kc);
2059 return False0;
2060 }
2061 if (haveActions)
2062 {
2063 outActs = XkbResizeKeyActions(xkb, kc, i);
2064 if (outActs == NULL((void*)0))
2065 {
2066 WSGO2uInternalError("Could not enlarge actions for %s (key %d)\n",
2067 longText(key->name, XkbMessage3), kc);
2068 return False0;
2069 }
2070 xkb->server->explicit[kc] |= XkbExplicitInterpretMask(1<<4);
2071 }
2072 else
2073 outActs = NULL((void*)0);
2074 if (key->defs.defined & _Key_GroupInfo(1<<6))
2075 i = key->groupInfo;
2076 else
2077 i = xkb->map->key_sym_map[kc].group_info;
2078
2079 xkb->map->key_sym_map[kc].group_info = XkbSetNumGroups(i, nGroups)(((i)&0xf0)|((nGroups)&0x0f));
2080 xkb->map->key_sym_map[kc].width = width;
2081 for (i = 0; i < nGroups; i++)
2082 {
2083 /* assign kt_index[i] to the index of the type in map->types.
2084 * kt_index[i] may have been set by a previous run (if we have two
2085 * layouts specified). Let's not overwrite it with the ONE_LEVEL
2086 * default group if we dont even have keys for this group anyway.
2087 *
2088 * FIXME: There should be a better fix for this.
2089 */
2090 if (key->numLevels[i])
2091 xkb->map->key_sym_map[kc].kt_index[i] = types[i];
2092 if (key->syms[i] != NULL((void*)0))
2093 {
2094 /* fill key to "width" symbols*/
2095 for (tmp = 0; tmp < width; tmp++)
2096 {
2097 if (tmp < key->numLevels[i])
2098 outSyms[tmp] = key->syms[i][tmp];
2099 else
2100 outSyms[tmp] = NoSymbol0L;
2101 if ((outActs != NULL((void*)0)) && (key->acts[i] != NULL((void*)0)))
2102 {
2103 if (tmp < key->numLevels[i])
2104 outActs[tmp] = key->acts[i][tmp];
2105 else
2106 outActs[tmp].type = XkbSA_NoAction0x00;
2107 }
2108 }
2109 }
2110 outSyms += width;
2111 if (outActs)
2112 outActs += width;
2113 }
2114 switch (key->behavior.type & XkbKB_OpMask0x7f)
2115 {
2116 case XkbKB_Default0x00:
2117 break;
2118 case XkbKB_Overlay10x03:
2119 case XkbKB_Overlay20x04:
2120 /* find key by name! */
2121 if (!FindNamedKey(xkb, key->nameForOverlayKey, &okc, True1,
2122 CreateKeyNames(xkb)((xkb)->flags&(1L << 0)), 0))
2123 {
2124 if (warningLevel >= 1)
2125 {
2126 WARN2uWarning("Key %s not found in %s keycodes\n",
2127 longText(key->nameForOverlayKey, XkbMessage3),
2128 XkbAtomText(NULL((void*)0), xkb->names->keycodes, XkbMessage3));
2129 ACTION1uAction("Not treating %s as an overlay key \n",
2130 longText(key->name, XkbMessage3));
2131 }
2132 break;
2133 }
2134 key->behavior.data = okc;
2135 default:
2136 xkb->server->behaviors[kc] = key->behavior;
2137 xkb->server->explicit[kc] |= XkbExplicitBehaviorMask(1<<6);
2138 break;
2139 }
2140 if (key->defs.defined & _Key_VModMap(1<<7))
2141 {
2142 xkb->server->vmodmap[kc] = key->vmodmap;
2143 xkb->server->explicit[kc] |= XkbExplicitVModMapMask(1<<7);
2144 }
2145 if (key->repeat != RepeatUndefined~((unsigned)0))
2146 {
2147 if (key->repeat == RepeatYes1)
2148 xkb->ctrls->per_key_repeat[kc / 8] |= (1 << (kc % 8));
2149 else
2150 xkb->ctrls->per_key_repeat[kc / 8] &= ~(1 << (kc % 8));
2151 xkb->server->explicit[kc] |= XkbExplicitAutoRepeatMask(1<<5);
2152 }
2153
2154 /* do the same thing for the next key */
2155 CopySymbolsDef(result, key, kc + 1);
2156 return True1;
2157}
2158
2159static Boolint
2160CopyModMapDef(XkbFileInfo * result, ModMapEntry * entry)
2161{
2162 unsigned kc;
2163 XkbDescPtr xkb;
2164
2165 xkb = result->xkb;
2166 if ((!entry->haveSymbol)
2167 &&
2168 (!FindNamedKey
2169 (xkb, entry->u.keyName, &kc, True1, CreateKeyNames(xkb)((xkb)->flags&(1L << 0)), 0)))
2170 {
2171 if (warningLevel >= 5)
2172 {
2173 WARN2uWarning("Key %s not found in %s keycodes\n",
2174 longText(entry->u.keyName, XkbMessage3),
2175 XkbAtomText(NULL((void*)0), xkb->names->keycodes, XkbMessage3));
2176 ACTION1uAction("Modifier map entry for %s not updated\n",
2177 XkbModIndexText(entry->modifier, XkbMessage3));
2178 }
2179 return False0;
2180 }
2181 else if (entry->haveSymbol
2182 && (!FindKeyForSymbol(xkb, entry->u.keySym, &kc)))
2183 {
2184 if (warningLevel > 5)
2185 {
2186 WARN2uWarning("Key \"%s\" not found in %s symbol map\n",
2187 XkbKeysymText(entry->u.keySym, XkbMessage3),
2188 XkbAtomText(NULL((void*)0), xkb->names->symbols, XkbMessage3));
2189 ACTION1uAction("Modifier map entry for %s not updated\n",
2190 XkbModIndexText(entry->modifier, XkbMessage3));
2191 }
2192 return False0;
2193 }
2194 xkb->map->modmap[kc] |= (1 << entry->modifier);
2195 return True1;
2196}
2197
2198/**
2199 * Handle the xkb_symbols section of an xkb file.
2200 *
2201 * @param file The parsed xkb_symbols section of the xkb file.
2202 * @param result Handle to the data to store the result in.
2203 * @param merge Merge strategy (e.g. MergeOverride).
2204 */
2205Boolint
2206CompileSymbols(XkbFile * file, XkbFileInfo * result, unsigned merge)
2207{
2208 register int i;
2209 SymbolsInfo info;
2210 XkbDescPtr xkb;
2211
2212 xkb = result->xkb;
2213 InitSymbolsInfo(&info, xkb);
2214 info.dflt.defs.fileID = file->id;
2215 info.dflt.defs.merge = merge;
2216 HandleSymbolsFile(file, xkb, merge, &info);
2217
2218 if (info.nKeys == 0)
2219 return True1;
2220 if (info.errorCount == 0)
2221 {
2222 KeyInfo *key;
2223
2224 /* alloc memory in the xkb struct */
2225 if (XkbAllocNames(xkb, XkbSymbolsNameMask(1<<2) | XkbGroupNamesMask(1<<12), 0, 0)
2226 != Success0)
2227 {
2228 WSGOuInternalError("Can not allocate names in CompileSymbols\n");
2229 ACTIONuAction("Symbols not added\n");
2230 return False0;
2231 }
2232 if (XkbAllocClientMap(xkb, XkbKeySymsMask(1<<1) | XkbModifierMapMask(1<<2), 0)
2233 != Success0)
2234 {
2235 WSGOuInternalError("Could not allocate client map in CompileSymbols\n");
2236 ACTIONuAction("Symbols not added\n");
2237 return False0;
2238 }
2239 if (XkbAllocServerMap(xkb, XkbAllServerInfoMask((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<
7))
, 32) != Success0)
2240 {
2241 WSGOuInternalError("Could not allocate server map in CompileSymbols\n");
2242 ACTIONuAction("Symbols not added\n");
2243 return False0;
2244 }
2245 if (XkbAllocControls(xkb, XkbPerKeyRepeatMask(1L << 30)) != Success0)
2246 {
2247 WSGOuInternalError("Could not allocate controls in CompileSymbols\n");
2248 ACTIONuAction("Symbols not added\n");
2249 return False0;
2250 }
2251
2252 /* now copy info into xkb. */
2253 xkb->names->symbols = XkbInternAtom(xkb->dpy, info.name, False0);
2254 if (info.aliases)
2255 ApplyAliases(xkb, False0, &info.aliases);
2256 for (i = 0; i < XkbNumKbdGroups4; i++)
2257 {
2258 if (info.groupNames[i] != None0L)
2259 xkb->names->groups[i] = info.groupNames[i];
2260 }
2261 /* sanitize keys */
2262 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2263 {
2264 PrepareKeyDef(key);
2265 }
2266 /* copy! */
2267 for (key = info.keys, i = 0; i < info.nKeys; i++, key++)
2268 {
2269 if (!CopySymbolsDef(result, key, 0))
2270 info.errorCount++;
2271 }
2272 if (warningLevel > 3)
2273 {
2274 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++)
2275 {
2276 if (xkb->names->keys[i].name[0] == '\0')
2277 continue;
2278 if (XkbKeyNumGroups(xkb, i)((((((xkb)->map)->key_sym_map[(i)].group_info)&0x0f
)))
< 1)
2279 {
2280 char buf[5];
2281 memcpy(buf, xkb->names->keys[i].name, 4);
2282 buf[4] = '\0';
2283 WARN2uWarning
2284 ("No symbols defined for <%s> (keycode %d)\n",
2285 buf, i);
2286 }
2287 }
2288 }
2289 if (info.modMap)
2290 {
2291 ModMapEntry *mm, *next;
2292 for (mm = info.modMap; mm != NULL((void*)0); mm = next)
2293 {
2294 if (!CopyModMapDef(result, mm))
2295 info.errorCount++;
2296 next = (ModMapEntry *) mm->defs.next;
2297 }
2298 }
2299 return True1;
2300 }
2301 return False0;
2302}