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 ********************************************************/
32 #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 = XkbcInternAtom("default", False);
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}
199 SetIndicatorMapField(LEDInfo * led,
201 char *field, ExprDef * arrayNdx, ExprDef * value)
207 if ((uStrCaseCmp(field, "modifiers") == 0)
208 || (uStrCaseCmp(field, "mods") == 0))
210 if (arrayNdx != NULL)
211 return ReportIndicatorNotArray(led, field);
212 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
213 return ReportIndicatorBadType(led, field, "modifier mask");
214 led->real_mods = rtrn.uval & 0xff;
215 led->vmods = (rtrn.uval >> 8) & 0xff;
216 led->defs.defined |= _LED_Mods;
218 else if (uStrCaseCmp(field, "groups") == 0)
220 if (arrayNdx != NULL)
221 return ReportIndicatorNotArray(led, field);
223 (value, &rtrn, SimpleLookup, (char *) groupNames))
224 return ReportIndicatorBadType(led, field, "group mask");
225 led->groups = rtrn.uval;
226 led->defs.defined |= _LED_Groups;
228 else if ((uStrCaseCmp(field, "controls") == 0) ||
229 (uStrCaseCmp(field, "ctrls") == 0))
231 if (arrayNdx != NULL)
232 return ReportIndicatorNotArray(led, field);
234 (value, &rtrn, SimpleLookup, (char *) ctrlNames))
235 return ReportIndicatorBadType(led, field,
237 led->ctrls = rtrn.uval;
238 led->defs.defined |= _LED_Ctrls;
240 else if (uStrCaseCmp(field, "allowexplicit") == 0)
242 if (arrayNdx != NULL)
243 return ReportIndicatorNotArray(led, field);
244 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
245 return ReportIndicatorBadType(led, field, "boolean");
247 led->flags &= ~XkbIM_NoExplicit;
249 led->flags |= XkbIM_NoExplicit;
250 led->defs.defined |= _LED_Explicit;
252 else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
253 (uStrCaseCmp(field, "whichmodifierstate") == 0))
255 if (arrayNdx != NULL)
256 return ReportIndicatorNotArray(led, field);
257 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
258 (char *) modComponentNames))
260 return ReportIndicatorBadType(led, field,
261 "mask of modifier state components");
263 led->which_mods = rtrn.uval;
265 else if (uStrCaseCmp(field, "whichgroupstate") == 0)
267 if (arrayNdx != NULL)
268 return ReportIndicatorNotArray(led, field);
269 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
270 (char *) groupComponentNames))
272 return ReportIndicatorBadType(led, field,
273 "mask of group state components");
275 led->which_groups = rtrn.uval;
277 else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
278 (uStrCaseCmp(field, "driveskeyboard") == 0) ||
279 (uStrCaseCmp(field, "leddriveskbd") == 0) ||
280 (uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
281 (uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
282 (uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
284 if (arrayNdx != NULL)
285 return ReportIndicatorNotArray(led, field);
286 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
287 return ReportIndicatorBadType(led, field, "boolean");
289 led->flags |= XkbIM_LEDDrivesKB;
291 led->flags &= ~XkbIM_LEDDrivesKB;
292 led->defs.defined |= _LED_DrivesKbd;
294 else if (uStrCaseCmp(field, "index") == 0)
296 if (arrayNdx != NULL)
297 return ReportIndicatorNotArray(led, field);
298 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
299 return ReportIndicatorBadType(led, field,
301 if ((rtrn.uval < 1) || (rtrn.uval > 32))
303 ERROR("Illegal indicator index %d (range 1..%d)\n",
304 rtrn.uval, XkbNumIndicators);
305 ACTION("Index definition for %s indicator ignored\n",
306 XkbcAtomText(led->name));
309 led->indicator = rtrn.uval;
310 led->defs.defined |= _LED_Index;
314 ERROR("Unknown field %s in map for %s indicator\n", field,
315 XkbcAtomText(led->name));
316 ACTION("Definition ignored\n");
323 HandleIndicatorMapDef(IndicatorMapDef * def,
325 LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
331 if (def->merge != MergeDefault)
335 led.defs.merge = merge;
336 led.name = def->name;
339 for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
341 ExprResult elem, field;
343 if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
348 if (elem.str != NULL)
351 ("Cannot set defaults for \"%s\" element in indicator map\n",
353 ACTION("Assignment to %s.%s ignored\n", elem.str, field.str);
358 ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
364 rtrn = AddIndicatorMap(oldLEDs, &led);
371 CopyIndicatorMapDefs(XkbcDescPtr xkb, LEDInfo *leds, LEDInfo **unboundRtrn)
374 LEDInfo *unbound, *last;
376 if (XkbcAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
378 WSGO("Couldn't allocate names\n");
379 ACTION("Indicator names may be incorrect\n");
381 if (XkbcAllocIndicatorMaps(xkb) != Success)
383 WSGO("Can't allocate indicator maps\n");
384 ACTION("Indicator map definitions may be lost\n");
387 last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
388 while ((last != NULL) && (last->defs.next != NULL))
390 last = (LEDInfo *) last->defs.next;
392 for (led = leds; led != NULL; led = next)
394 next = (LEDInfo *) led->defs.next;
395 if ((led->groups != 0) && (led->which_groups == 0))
396 led->which_groups = XkbIM_UseEffective;
397 if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
398 led->which_mods = XkbIM_UseEffective;
399 if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
401 if (unboundRtrn != NULL)
403 led->defs.next = NULL;
405 last->defs.next = (CommonInfo *) led;
415 register XkbIndicatorMapPtr im;
416 im = &xkb->indicators->maps[led->indicator - 1];
417 im->flags = led->flags;
418 im->which_groups = led->which_groups;
419 im->groups = led->groups;
420 im->which_mods = led->which_mods;
421 im->mods.mask = led->real_mods;
422 im->mods.real_mods = led->real_mods;
423 im->mods.vmods = led->vmods;
424 im->ctrls = led->ctrls;
425 if (xkb->names != NULL)
426 xkb->names->indicators[led->indicator - 1] = led->name;
430 if (unboundRtrn != NULL)
432 *unboundRtrn = unbound;
438 BindIndicators(XkbcDescPtr xkb, Bool force, LEDInfo *unbound,
439 LEDInfo **unboundRtrn)
442 register LEDInfo *led, *next, *last;
444 if (xkb->names != NULL)
446 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
448 if (led->indicator == _LED_NotBound)
450 for (i = 0; i < XkbNumIndicators; i++)
452 if (xkb->names->indicators[i] == led->name)
454 led->indicator = i + 1;
462 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
464 if (led->indicator == _LED_NotBound)
466 for (i = 0; i < XkbNumIndicators; i++)
468 if (xkb->names->indicators[i] == None)
470 xkb->names->indicators[i] = led->name;
471 led->indicator = i + 1;
472 xkb->indicators->phys_indicators &= ~(1 << i);
476 if (led->indicator == _LED_NotBound)
478 ERROR("No unnamed indicators found\n");
480 ("Virtual indicator map \"%s\" not bound\n",
481 XkbcAtomGetString(led->name));
488 for (last = NULL, led = unbound; led != NULL; led = next)
490 next = (LEDInfo *) led->defs.next;
491 if (led->indicator == _LED_NotBound)
501 last->defs.next = &led->defs;
509 if ((xkb->names != NULL) &&
510 (xkb->names->indicators[led->indicator - 1] != led->name))
512 Atom old = xkb->names->indicators[led->indicator - 1];
513 ERROR("Multiple names bound to indicator %d\n",
514 (unsigned int) led->indicator);
515 ACTION("Using %s, ignoring %s\n",
516 XkbcAtomGetString(old),
517 XkbcAtomGetString(led->name));
518 led->indicator = _LED_NotBound;
527 last->defs.next = &led->defs;
535 XkbIndicatorMapPtr map;
536 map = &xkb->indicators->maps[led->indicator - 1];
537 map->flags = led->flags;
538 map->which_groups = led->which_groups;
539 map->groups = led->groups;
540 map->which_mods = led->which_mods;
541 map->mods.mask = led->real_mods;
542 map->mods.real_mods = led->real_mods;
543 map->mods.vmods = led->vmods;
544 map->ctrls = led->ctrls;
546 last->defs.next = &next->defs;
549 led->defs.next = NULL;
556 *unboundRtrn = unbound;
560 for (led = unbound; led != NULL; led = next)
562 next = (LEDInfo *) led->defs.next;