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 ********************************************************/
27 #include "indicators.h"
31 /***====================================================================***/
33 #define ReportIndicatorBadType(l, f, w) \
34 ReportBadType("indicator map", (f), XkbcAtomText((l)->name), (w))
35 #define ReportIndicatorNotArray(l, f) \
36 ReportNotArray("indicator map", (f), XkbcAtomText((l)->name))
38 /***====================================================================***/
41 ClearIndicatorMapInfo(LEDInfo * info)
43 info->name = xkb_intern_atom("default");
44 info->indicator = _LED_NotBound;
45 info->flags = info->which_mods = info->real_mods = 0;
47 info->which_groups = info->groups = 0;
52 AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new)
58 for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next)
60 if (old->name == new->name)
62 if ((old->real_mods == new->real_mods) &&
63 (old->vmods == new->vmods) &&
64 (old->groups == new->groups) &&
65 (old->ctrls == new->ctrls) &&
66 (old->which_mods == new->which_mods) &&
67 (old->which_groups == new->which_groups))
69 old->defs.defined |= new->defs.defined;
72 if (new->defs.merge == MergeReplace)
74 CommonInfo *next = old->defs.next;
75 if (((old->defs.fileID == new->defs.fileID)
76 && (warningLevel > 0)) || (warningLevel > 9))
78 WARN("Map for indicator %s redefined\n",
79 XkbcAtomText(old->name));
80 ACTION("Earlier definition ignored\n");
83 old->defs.next = next;
87 if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide))
89 old->indicator = new->indicator;
90 old->defs.defined |= _LED_Index;
92 if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide))
94 old->which_mods = new->which_mods;
95 old->real_mods = new->real_mods;
96 old->vmods = new->vmods;
97 old->defs.defined |= _LED_Mods;
99 if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide))
101 old->which_groups = new->which_groups;
102 old->groups = new->groups;
103 old->defs.defined |= _LED_Groups;
105 if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide))
107 old->ctrls = new->ctrls;
108 old->defs.defined |= _LED_Ctrls;
110 if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide))
112 old->flags &= ~XkbIM_NoExplicit;
113 old->flags |= (new->flags & XkbIM_NoExplicit);
114 old->defs.defined |= _LED_Explicit;
116 if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide))
118 old->flags &= ~XkbIM_NoAutomatic;
119 old->flags |= (new->flags & XkbIM_NoAutomatic);
120 old->defs.defined |= _LED_Automatic;
122 if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide))
124 old->flags &= ~XkbIM_LEDDrivesKB;
125 old->flags |= (new->flags & XkbIM_LEDDrivesKB);
126 old->defs.defined |= _LED_DrivesKbd;
130 WARN("Map for indicator %s redefined\n",
131 XkbcAtomText(old->name));
132 ACTION("Using %s definition for duplicate fields\n",
133 (new->defs.merge == MergeAugment ? "first" : "last"));
137 if (old->defs.next == NULL)
141 old = uTypedAlloc(LEDInfo);
144 WSGO("Couldn't allocate indicator map\n");
145 ACTION("Map for indicator %s not compiled\n",
146 XkbcAtomText(new->name));
150 old->defs.next = NULL;
153 last->defs.next = &old->defs;
159 static const LookupEntry modComponentNames[] = {
160 {"base", XkbIM_UseBase},
161 {"latched", XkbIM_UseLatched},
162 {"locked", XkbIM_UseLocked},
163 {"effective", XkbIM_UseEffective},
164 {"compat", XkbIM_UseCompat},
165 {"any", XkbIM_UseAnyMods},
169 static const LookupEntry groupComponentNames[] = {
170 {"base", XkbIM_UseBase},
171 {"latched", XkbIM_UseLatched},
172 {"locked", XkbIM_UseLocked},
173 {"effective", XkbIM_UseEffective},
174 {"any", XkbIM_UseAnyGroup},
179 static const LookupEntry groupNames[] = {
194 SetIndicatorMapField(LEDInfo * led,
195 struct xkb_keymap * xkb,
196 char *field, ExprDef * arrayNdx, ExprDef * value)
202 if ((strcasecmp(field, "modifiers") == 0) ||
203 (strcasecmp(field, "mods") == 0))
205 if (arrayNdx != NULL)
206 return ReportIndicatorNotArray(led, field);
207 if (!ExprResolveVModMask(value, &rtrn, xkb))
208 return ReportIndicatorBadType(led, field, "modifier mask");
209 led->real_mods = rtrn.uval & 0xff;
210 led->vmods = (rtrn.uval >> 8) & 0xff;
211 led->defs.defined |= _LED_Mods;
213 else if (strcasecmp(field, "groups") == 0)
215 if (arrayNdx != NULL)
216 return ReportIndicatorNotArray(led, field);
217 if (!ExprResolveMask(value, &rtrn, groupNames))
218 return ReportIndicatorBadType(led, field, "group mask");
219 led->groups = rtrn.uval;
220 led->defs.defined |= _LED_Groups;
222 else if ((strcasecmp(field, "controls") == 0) ||
223 (strcasecmp(field, "ctrls") == 0))
225 if (arrayNdx != NULL)
226 return ReportIndicatorNotArray(led, field);
227 if (!ExprResolveMask(value, &rtrn, ctrlNames))
228 return ReportIndicatorBadType(led, field,
230 led->ctrls = rtrn.uval;
231 led->defs.defined |= _LED_Ctrls;
233 else if (strcasecmp(field, "allowexplicit") == 0)
235 if (arrayNdx != NULL)
236 return ReportIndicatorNotArray(led, field);
237 if (!ExprResolveBoolean(value, &rtrn))
238 return ReportIndicatorBadType(led, field, "boolean");
240 led->flags &= ~XkbIM_NoExplicit;
242 led->flags |= XkbIM_NoExplicit;
243 led->defs.defined |= _LED_Explicit;
245 else if ((strcasecmp(field, "whichmodstate") == 0) ||
246 (strcasecmp(field, "whichmodifierstate") == 0))
248 if (arrayNdx != NULL)
249 return ReportIndicatorNotArray(led, field);
250 if (!ExprResolveMask(value, &rtrn, modComponentNames))
252 return ReportIndicatorBadType(led, field,
253 "mask of modifier state components");
255 led->which_mods = rtrn.uval;
257 else if (strcasecmp(field, "whichgroupstate") == 0)
259 if (arrayNdx != NULL)
260 return ReportIndicatorNotArray(led, field);
261 if (!ExprResolveMask(value, &rtrn, groupComponentNames))
263 return ReportIndicatorBadType(led, field,
264 "mask of group state components");
266 led->which_groups = rtrn.uval;
268 else if ((strcasecmp(field, "driveskbd") == 0) ||
269 (strcasecmp(field, "driveskeyboard") == 0) ||
270 (strcasecmp(field, "leddriveskbd") == 0) ||
271 (strcasecmp(field, "leddriveskeyboard") == 0) ||
272 (strcasecmp(field, "indicatordriveskbd") == 0) ||
273 (strcasecmp(field, "indicatordriveskeyboard") == 0))
275 if (arrayNdx != NULL)
276 return ReportIndicatorNotArray(led, field);
277 if (!ExprResolveBoolean(value, &rtrn))
278 return ReportIndicatorBadType(led, field, "boolean");
280 led->flags |= XkbIM_LEDDrivesKB;
282 led->flags &= ~XkbIM_LEDDrivesKB;
283 led->defs.defined |= _LED_DrivesKbd;
285 else if (strcasecmp(field, "index") == 0)
287 if (arrayNdx != NULL)
288 return ReportIndicatorNotArray(led, field);
289 if (!ExprResolveInteger(value, &rtrn))
290 return ReportIndicatorBadType(led, field,
292 if ((rtrn.uval < 1) || (rtrn.uval > 32))
294 ERROR("Illegal indicator index %d (range 1..%d)\n",
295 rtrn.uval, XkbNumIndicators);
296 ACTION("Index definition for %s indicator ignored\n",
297 XkbcAtomText(led->name));
300 led->indicator = rtrn.uval;
301 led->defs.defined |= _LED_Index;
305 ERROR("Unknown field %s in map for %s indicator\n", field,
306 XkbcAtomText(led->name));
307 ACTION("Definition ignored\n");
314 HandleIndicatorMapDef(IndicatorMapDef * def,
315 struct xkb_keymap * xkb,
316 LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
322 if (def->merge != MergeDefault)
326 led.defs.merge = merge;
327 led.name = def->name;
330 for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
332 ExprResult elem, field;
334 if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
339 if (elem.str != NULL)
342 ("Cannot set defaults for \"%s\" element in indicator map\n",
344 ACTION("Assignment to %s.%s ignored\n", elem.str, field.str);
349 ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
357 rtrn = AddIndicatorMap(oldLEDs, &led);
364 CopyIndicatorMapDefs(struct xkb_keymap * xkb, LEDInfo *leds, LEDInfo **unboundRtrn)
367 LEDInfo *unbound, *last;
369 if (XkbcAllocNames(xkb, XkbIndicatorNamesMask, 0) != Success)
371 WSGO("Couldn't allocate names\n");
372 ACTION("Indicator names may be incorrect\n");
374 if (XkbcAllocIndicatorMaps(xkb) != Success)
376 WSGO("Can't allocate indicator maps\n");
377 ACTION("Indicator map definitions may be lost\n");
380 last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
381 while ((last != NULL) && (last->defs.next != NULL))
383 last = (LEDInfo *) last->defs.next;
385 for (led = leds; led != NULL; led = next)
387 next = (LEDInfo *) led->defs.next;
388 if ((led->groups != 0) && (led->which_groups == 0))
389 led->which_groups = XkbIM_UseEffective;
390 if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
391 led->which_mods = XkbIM_UseEffective;
392 if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
394 if (unboundRtrn != NULL)
396 led->defs.next = NULL;
398 last->defs.next = (CommonInfo *) led;
408 struct xkb_indicator_map * im;
409 im = &xkb->indicators->maps[led->indicator - 1];
410 im->flags = led->flags;
411 im->which_groups = led->which_groups;
412 im->groups = led->groups;
413 im->which_mods = led->which_mods;
414 im->mods.mask = led->real_mods;
415 im->mods.real_mods = led->real_mods;
416 im->mods.vmods = led->vmods;
417 im->ctrls = led->ctrls;
418 if (xkb->names != NULL)
420 free(UNCONSTIFY(xkb->names->indicators[led->indicator - 1]));
421 xkb->names->indicators[led->indicator-1] = XkbcAtomGetString(led->name);
426 if (unboundRtrn != NULL)
428 *unboundRtrn = unbound;
434 BindIndicators(struct xkb_keymap * xkb, bool force, LEDInfo *unbound,
435 LEDInfo **unboundRtrn)
438 LEDInfo *led, *next, *last;
440 if (xkb->names != NULL)
442 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
444 if (led->indicator == _LED_NotBound)
446 for (i = 0; i < XkbNumIndicators; i++)
448 if (xkb->names->indicators[i] &&
449 strcmp(xkb->names->indicators[i],
450 XkbcAtomText(led->name)) == 0)
452 led->indicator = i + 1;
460 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
462 if (led->indicator == _LED_NotBound)
464 for (i = 0; i < XkbNumIndicators; i++)
466 if (xkb->names->indicators[i] == NULL)
468 xkb->names->indicators[i] = XkbcAtomGetString(led->name);
469 led->indicator = i + 1;
473 if (led->indicator == _LED_NotBound)
475 ERROR("No unnamed indicators found\n");
477 ("Virtual indicator map \"%s\" not bound\n",
478 XkbcAtomText(led->name));
485 for (last = NULL, led = unbound; led != NULL; led = next)
487 next = (LEDInfo *) led->defs.next;
488 if (led->indicator == _LED_NotBound)
498 last->defs.next = &led->defs;
506 if ((xkb->names != NULL) &&
507 (strcmp(xkb->names->indicators[led->indicator - 1],
508 XkbcAtomText(led->name)) != 0))
510 const char *old = xkb->names->indicators[led->indicator - 1];
511 ERROR("Multiple names bound to indicator %d\n",
512 (unsigned int) led->indicator);
513 ACTION("Using %s, ignoring %s\n", old, XkbcAtomText(led->name));
514 led->indicator = _LED_NotBound;
523 last->defs.next = &led->defs;
531 struct xkb_indicator_map * map;
532 map = &xkb->indicators->maps[led->indicator - 1];
533 map->flags = led->flags;
534 map->which_groups = led->which_groups;
535 map->groups = led->groups;
536 map->which_mods = led->which_mods;
537 map->mods.mask = led->real_mods;
538 map->mods.real_mods = led->real_mods;
539 map->mods.vmods = led->vmods;
540 map->ctrls = led->ctrls;
542 last->defs.next = &next->defs;
545 led->defs.next = NULL;
552 *unboundRtrn = unbound;
556 for (led = unbound; led != NULL; led = next)
558 next = led ? (LEDInfo *) led->defs.next : NULL;