Bug Summary

File:symbols.c
Location:line 641, column 32
Description:The left operand of '!=' is a garbage value

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