1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
33 #include "indicators.h"
36 /***====================================================================***/
38 #define ReportIndicatorBadType(l, f, w) \
39 ReportBadType("indicator map", (f), XkbcAtomText((l)->name), (w))
40 #define ReportIndicatorNotArray(l, f) \
41 ReportNotArray("indicator map", (f), XkbcAtomText((l)->name))
43 /***====================================================================***/
46 ClearIndicatorMapInfo(LEDInfo * info)
48 info->name = xkb_intern_atom("default");
49 info->indicator = _LED_NotBound;
50 info->flags = info->which_mods = info->real_mods = 0;
52 info->which_groups = info->groups = 0;
58 AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new)
64 for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next)
66 if (old->name == new->name)
68 if ((old->real_mods == new->real_mods) &&
69 (old->vmods == new->vmods) &&
70 (old->groups == new->groups) &&
71 (old->ctrls == new->ctrls) &&
72 (old->which_mods == new->which_mods) &&
73 (old->which_groups == new->which_groups))
75 old->defs.defined |= new->defs.defined;
78 if (new->defs.merge == MergeReplace)
80 CommonInfo *next = old->defs.next;
81 if (((old->defs.fileID == new->defs.fileID)
82 && (warningLevel > 0)) || (warningLevel > 9))
84 WARN("Map for indicator %s redefined\n",
85 XkbcAtomText(old->name));
86 ACTION("Earlier definition ignored\n");
89 old->defs.next = next;
93 if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide))
95 old->indicator = new->indicator;
96 old->defs.defined |= _LED_Index;
98 if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide))
100 old->which_mods = new->which_mods;
101 old->real_mods = new->real_mods;
102 old->vmods = new->vmods;
103 old->defs.defined |= _LED_Mods;
105 if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide))
107 old->which_groups = new->which_groups;
108 old->groups = new->groups;
109 old->defs.defined |= _LED_Groups;
111 if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide))
113 old->ctrls = new->ctrls;
114 old->defs.defined |= _LED_Ctrls;
116 if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide))
118 old->flags &= ~XkbIM_NoExplicit;
119 old->flags |= (new->flags & XkbIM_NoExplicit);
120 old->defs.defined |= _LED_Explicit;
122 if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide))
124 old->flags &= ~XkbIM_NoAutomatic;
125 old->flags |= (new->flags & XkbIM_NoAutomatic);
126 old->defs.defined |= _LED_Automatic;
128 if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide))
130 old->flags &= ~XkbIM_LEDDrivesKB;
131 old->flags |= (new->flags & XkbIM_LEDDrivesKB);
132 old->defs.defined |= _LED_DrivesKbd;
136 WARN("Map for indicator %s redefined\n",
137 XkbcAtomText(old->name));
138 ACTION("Using %s definition for duplicate fields\n",
139 (new->defs.merge == MergeAugment ? "first" : "last"));
143 if (old->defs.next == NULL)
147 old = uTypedAlloc(LEDInfo);
150 WSGO("Couldn't allocate indicator map\n");
151 ACTION("Map for indicator %s not compiled\n",
152 XkbcAtomText(new->name));
156 old->defs.next = NULL;
159 last->defs.next = &old->defs;
165 static LookupEntry modComponentNames[] = {
166 {"base", XkbIM_UseBase}
168 {"latched", XkbIM_UseLatched}
170 {"locked", XkbIM_UseLocked}
172 {"effective", XkbIM_UseEffective}
174 {"compat", XkbIM_UseCompat}
176 {"any", XkbIM_UseAnyMods}
182 static LookupEntry groupComponentNames[] = {
183 {"base", XkbIM_UseBase}
185 {"latched", XkbIM_UseLatched}
187 {"locked", XkbIM_UseLocked}
189 {"effective", XkbIM_UseEffective}
191 {"any", XkbIM_UseAnyGroup}
198 static LookupEntry groupNames[] = {
223 SetIndicatorMapField(LEDInfo * led,
224 struct xkb_desc * xkb,
225 char *field, ExprDef * arrayNdx, ExprDef * value)
231 if ((uStrCaseCmp(field, "modifiers") == 0)
232 || (uStrCaseCmp(field, "mods") == 0))
234 if (arrayNdx != NULL)
235 return ReportIndicatorNotArray(led, field);
236 if (!ExprResolveVModMask(value, &rtrn, xkb))
237 return ReportIndicatorBadType(led, field, "modifier mask");
238 led->real_mods = rtrn.uval & 0xff;
239 led->vmods = (rtrn.uval >> 8) & 0xff;
240 led->defs.defined |= _LED_Mods;
242 else if (uStrCaseCmp(field, "groups") == 0)
244 if (arrayNdx != NULL)
245 return ReportIndicatorNotArray(led, field);
246 if (!ExprResolveMask(value, &rtrn, groupNames))
247 return ReportIndicatorBadType(led, field, "group mask");
248 led->groups = rtrn.uval;
249 led->defs.defined |= _LED_Groups;
251 else if ((uStrCaseCmp(field, "controls") == 0) ||
252 (uStrCaseCmp(field, "ctrls") == 0))
254 if (arrayNdx != NULL)
255 return ReportIndicatorNotArray(led, field);
256 if (!ExprResolveMask(value, &rtrn, ctrlNames))
257 return ReportIndicatorBadType(led, field,
259 led->ctrls = rtrn.uval;
260 led->defs.defined |= _LED_Ctrls;
262 else if (uStrCaseCmp(field, "allowexplicit") == 0)
264 if (arrayNdx != NULL)
265 return ReportIndicatorNotArray(led, field);
266 if (!ExprResolveBoolean(value, &rtrn))
267 return ReportIndicatorBadType(led, field, "boolean");
269 led->flags &= ~XkbIM_NoExplicit;
271 led->flags |= XkbIM_NoExplicit;
272 led->defs.defined |= _LED_Explicit;
274 else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
275 (uStrCaseCmp(field, "whichmodifierstate") == 0))
277 if (arrayNdx != NULL)
278 return ReportIndicatorNotArray(led, field);
279 if (!ExprResolveMask(value, &rtrn, modComponentNames))
281 return ReportIndicatorBadType(led, field,
282 "mask of modifier state components");
284 led->which_mods = rtrn.uval;
286 else if (uStrCaseCmp(field, "whichgroupstate") == 0)
288 if (arrayNdx != NULL)
289 return ReportIndicatorNotArray(led, field);
290 if (!ExprResolveMask(value, &rtrn, groupComponentNames))
292 return ReportIndicatorBadType(led, field,
293 "mask of group state components");
295 led->which_groups = rtrn.uval;
297 else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
298 (uStrCaseCmp(field, "driveskeyboard") == 0) ||
299 (uStrCaseCmp(field, "leddriveskbd") == 0) ||
300 (uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
301 (uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
302 (uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
304 if (arrayNdx != NULL)
305 return ReportIndicatorNotArray(led, field);
306 if (!ExprResolveBoolean(value, &rtrn))
307 return ReportIndicatorBadType(led, field, "boolean");
309 led->flags |= XkbIM_LEDDrivesKB;
311 led->flags &= ~XkbIM_LEDDrivesKB;
312 led->defs.defined |= _LED_DrivesKbd;
314 else if (uStrCaseCmp(field, "index") == 0)
316 if (arrayNdx != NULL)
317 return ReportIndicatorNotArray(led, field);
318 if (!ExprResolveInteger(value, &rtrn))
319 return ReportIndicatorBadType(led, field,
321 if ((rtrn.uval < 1) || (rtrn.uval > 32))
323 ERROR("Illegal indicator index %d (range 1..%d)\n",
324 rtrn.uval, XkbNumIndicators);
325 ACTION("Index definition for %s indicator ignored\n",
326 XkbcAtomText(led->name));
329 led->indicator = rtrn.uval;
330 led->defs.defined |= _LED_Index;
334 ERROR("Unknown field %s in map for %s indicator\n", field,
335 XkbcAtomText(led->name));
336 ACTION("Definition ignored\n");
343 HandleIndicatorMapDef(IndicatorMapDef * def,
344 struct xkb_desc * xkb,
345 LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
351 if (def->merge != MergeDefault)
355 led.defs.merge = merge;
356 led.name = def->name;
359 for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
361 ExprResult elem, field;
363 if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
368 if (elem.str != NULL)
371 ("Cannot set defaults for \"%s\" element in indicator map\n",
373 ACTION("Assignment to %s.%s ignored\n", elem.str, field.str);
378 ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
386 rtrn = AddIndicatorMap(oldLEDs, &led);
393 CopyIndicatorMapDefs(struct xkb_desc * xkb, LEDInfo *leds, LEDInfo **unboundRtrn)
396 LEDInfo *unbound, *last;
398 if (XkbcAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
400 WSGO("Couldn't allocate names\n");
401 ACTION("Indicator names may be incorrect\n");
403 if (XkbcAllocIndicatorMaps(xkb) != Success)
405 WSGO("Can't allocate indicator maps\n");
406 ACTION("Indicator map definitions may be lost\n");
409 last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
410 while ((last != NULL) && (last->defs.next != NULL))
412 last = (LEDInfo *) last->defs.next;
414 for (led = leds; led != NULL; led = next)
416 next = (LEDInfo *) led->defs.next;
417 if ((led->groups != 0) && (led->which_groups == 0))
418 led->which_groups = XkbIM_UseEffective;
419 if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
420 led->which_mods = XkbIM_UseEffective;
421 if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
423 if (unboundRtrn != NULL)
425 led->defs.next = NULL;
427 last->defs.next = (CommonInfo *) led;
437 register struct xkb_indicator_map * im;
438 im = &xkb->indicators->maps[led->indicator - 1];
439 im->flags = led->flags;
440 im->which_groups = led->which_groups;
441 im->groups = led->groups;
442 im->which_mods = led->which_mods;
443 im->mods.mask = led->real_mods;
444 im->mods.real_mods = led->real_mods;
445 im->mods.vmods = led->vmods;
446 im->ctrls = led->ctrls;
447 if (xkb->names != NULL)
448 xkb->names->indicators[led->indicator - 1] = led->name;
452 if (unboundRtrn != NULL)
454 *unboundRtrn = unbound;
460 BindIndicators(struct xkb_desc * xkb, Bool force, LEDInfo *unbound,
461 LEDInfo **unboundRtrn)
464 register LEDInfo *led, *next, *last;
466 if (xkb->names != NULL)
468 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
470 if (led->indicator == _LED_NotBound)
472 for (i = 0; i < XkbNumIndicators; i++)
474 if (xkb->names->indicators[i] == led->name)
476 led->indicator = i + 1;
484 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
486 if (led->indicator == _LED_NotBound)
488 for (i = 0; i < XkbNumIndicators; i++)
490 if (xkb->names->indicators[i] == None)
492 xkb->names->indicators[i] = led->name;
493 led->indicator = i + 1;
494 xkb->indicators->phys_indicators &= ~(1 << i);
498 if (led->indicator == _LED_NotBound)
500 ERROR("No unnamed indicators found\n");
502 ("Virtual indicator map \"%s\" not bound\n",
503 XkbcAtomText(led->name));
510 for (last = NULL, led = unbound; led != NULL; led = next)
512 next = (LEDInfo *) led->defs.next;
513 if (led->indicator == _LED_NotBound)
523 last->defs.next = &led->defs;
531 if ((xkb->names != NULL) &&
532 (xkb->names->indicators[led->indicator - 1] != led->name))
534 uint32_t old = xkb->names->indicators[led->indicator - 1];
535 ERROR("Multiple names bound to indicator %d\n",
536 (unsigned int) led->indicator);
537 ACTION("Using %s, ignoring %s\n",
539 XkbcAtomText(led->name));
540 led->indicator = _LED_NotBound;
549 last->defs.next = &led->defs;
557 struct xkb_indicator_map * map;
558 map = &xkb->indicators->maps[led->indicator - 1];
559 map->flags = led->flags;
560 map->which_groups = led->which_groups;
561 map->groups = led->groups;
562 map->which_mods = led->which_mods;
563 map->mods.mask = led->real_mods;
564 map->mods.real_mods = led->real_mods;
565 map->mods.vmods = led->vmods;
566 map->ctrls = led->ctrls;
568 last->defs.next = &next->defs;
571 led->defs.next = NULL;
578 *unboundRtrn = unbound;
582 for (led = unbound; led != NULL; led = next)
584 next = led ? (LEDInfo *) led->defs.next : NULL;