File: | symbols.c |
Location: | line 641, column 32 |
Description: | The left operand of '!=' is a garbage value |
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 | ||||
58 | typedef 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 | */ | |||
81 | static void | |||
82 | InitKeyInfo(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 | */ | |||
114 | static void | |||
115 | FreeKeyInfo(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 | */ | |||
151 | static Boolint | |||
152 | CopyKeyInfo(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 | ||||
203 | typedef 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 | |||
217 | typedef 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 | ||||
237 | static void | |||
238 | InitSymbolsInfo(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 | ||||
264 | static void | |||
265 | FreeSymbolsInfo(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 | ||||
295 | static Boolint | |||
296 | ResizeKeyGroup(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 | ||||
329 | static Boolint | |||
330 | MergeKeyGroups(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 | ||||
477 | static Boolint | |||
478 | MergeKeys(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 | ||||
601 | static Boolint | |||
602 | AddKeySymbols(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 | ||||
635 | static Boolint | |||
636 | AddModMapEntry(SymbolsInfo * info, ModMapEntry * new) | |||
637 | { | |||
638 | ModMapEntry *mm; | |||
639 | Boolint clobber; | |||
640 | ||||
641 | clobber = (new->defs.merge != MergeAugment1); | |||
| ||||
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 | ||||
712 | static void | |||
713 | MergeIncludedSymbols(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 | ||||
763 | typedef void (*FileHandler) (XkbFile * /* rtrn */ , | |||
764 | XkbDescPtr /* xkb */ , | |||
765 | unsigned /* merge */ , | |||
766 | SymbolsInfo * /* included */ | |||
767 | ); | |||
768 | ||||
769 | static Boolint | |||
770 | HandleIncludeSymbols(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 | ||||
860 | static 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 | ||||
876 | static Boolint | |||
877 | GetGroupIndex(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 | ||||
929 | static Boolint | |||
930 | AddSymbolsToKey(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 | ||||
983 | static Boolint | |||
984 | AddActionsToKey(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 | ||||
1049 | static int | |||
1050 | SetAllowNone(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 | ||||
1092 | static 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 | ||||
1103 | static 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 | ||||
1114 | static LookupEntry rgEntries[] = { | |||
1115 | {"none", 0}, | |||
1116 | {NULL((void*)0), 0} | |||
1117 | }; | |||
1118 | ||||
1119 | static Boolint | |||
1120 | SetSymbolsField(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 | ||||
1368 | static int | |||
1369 | SetGroupName(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 | ||||
1406 | static int | |||
1407 | HandleSymbolsVar(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 | ||||
1487 | static Boolint | |||
1488 | HandleSymbolsBody(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 | ||||
1525 | static Boolint | |||
1526 | SetExplicitGroup(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 | ||||
1565 | static int | |||
1566 | HandleSymbolsDef(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 | ||||
1595 | static Boolint | |||
1596 | HandleModMapDef(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)) | |||
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) | |||
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))) | |||
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; | |||
1634 | } | |||
1635 | return ok; | |||
1636 | } | |||
1637 | ||||
1638 | static void | |||
1639 | HandleSymbolsFile(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) | |||
1647 | { | |||
1648 | switch (stmt->stmtType) | |||
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)) | |||
1679 | info->errorCount++; | |||
1680 | break; | |||
1681 | default: | |||
1682 | WSGO1uInternalError("Unexpected statement type %d in HandleSymbolsFile\n", | |||
1683 | stmt->stmtType); | |||
1684 | break; | |||
1685 | } | |||
1686 | stmt = stmt->next; | |||
1687 | if (info->errorCount > 10) | |||
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 | ||||
1699 | static Boolint | |||
1700 | FindKeyForSymbol(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 | */ | |||
1735 | static Boolint | |||
1736 | FindNamedType(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 | ||||
1754 | static Boolint | |||
1755 | KSIsLower(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 | ||||
1765 | static Boolint | |||
1766 | KSIsUpper(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 | */ | |||
1792 | static Boolint | |||
1793 | FindAutomaticType(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 | */ | |||
1843 | static void | |||
1844 | PrepareKeyDef(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 | */ | |||
1953 | static Boolint | |||
1954 | CopySymbolsDef(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 | ||||
2160 | static Boolint | |||
2161 | CopyModMapDef(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 | */ | |||
2206 | Boolint | |||
2207 | CompileSymbols(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); | |||
| ||||
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 | } |