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 ********************************************************/
34 #include "indicators.h"
38 /***====================================================================***/
40 #define ReportIndicatorBadType(l, f, w) \
41 ReportBadType("indicator map", (f), XkbcAtomText((l)->name), (w))
42 #define ReportIndicatorNotArray(l, f) \
43 ReportNotArray("indicator map", (f), XkbcAtomText((l)->name))
45 /***====================================================================***/
48 ClearIndicatorMapInfo(LEDInfo * info)
50 info->name = XkbcInternAtom("default", False);
51 info->indicator = _LED_NotBound;
52 info->flags = info->which_mods = info->real_mods = 0;
54 info->which_groups = info->groups = 0;
60 AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new)
66 for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next)
68 if (old->name == new->name)
70 if ((old->real_mods == new->real_mods) &&
71 (old->vmods == new->vmods) &&
72 (old->groups == new->groups) &&
73 (old->ctrls == new->ctrls) &&
74 (old->which_mods == new->which_mods) &&
75 (old->which_groups == new->which_groups))
77 old->defs.defined |= new->defs.defined;
80 if (new->defs.merge == MergeReplace)
82 CommonInfo *next = old->defs.next;
83 if (((old->defs.fileID == new->defs.fileID)
84 && (warningLevel > 0)) || (warningLevel > 9))
86 WARN("Map for indicator %s redefined\n",
87 XkbcAtomText(old->name));
88 ACTION("Earlier definition ignored\n");
91 old->defs.next = next;
95 if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide))
97 old->indicator = new->indicator;
98 old->defs.defined |= _LED_Index;
100 if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide))
102 old->which_mods = new->which_mods;
103 old->real_mods = new->real_mods;
104 old->vmods = new->vmods;
105 old->defs.defined |= _LED_Mods;
107 if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide))
109 old->which_groups = new->which_groups;
110 old->groups = new->groups;
111 old->defs.defined |= _LED_Groups;
113 if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide))
115 old->ctrls = new->ctrls;
116 old->defs.defined |= _LED_Ctrls;
118 if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide))
120 old->flags &= ~XkbIM_NoExplicit;
121 old->flags |= (new->flags & XkbIM_NoExplicit);
122 old->defs.defined |= _LED_Explicit;
124 if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide))
126 old->flags &= ~XkbIM_NoAutomatic;
127 old->flags |= (new->flags & XkbIM_NoAutomatic);
128 old->defs.defined |= _LED_Automatic;
130 if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide))
132 old->flags &= ~XkbIM_LEDDrivesKB;
133 old->flags |= (new->flags & XkbIM_LEDDrivesKB);
134 old->defs.defined |= _LED_DrivesKbd;
138 WARN("Map for indicator %s redefined\n",
139 XkbcAtomText(old->name));
140 ACTION("Using %s definition for duplicate fields\n",
141 (new->defs.merge == MergeAugment ? "first" : "last"));
145 if (old->defs.next == NULL)
149 old = uTypedAlloc(LEDInfo);
152 WSGO("Couldn't allocate indicator map\n");
153 ACTION("Map for indicator %s not compiled\n",
154 XkbcAtomText(new->name));
158 old->defs.next = NULL;
161 last->defs.next = &old->defs;
167 static LookupEntry modComponentNames[] = {
168 {"base", XkbIM_UseBase}
170 {"latched", XkbIM_UseLatched}
172 {"locked", XkbIM_UseLocked}
174 {"effective", XkbIM_UseEffective}
176 {"compat", XkbIM_UseCompat}
178 {"any", XkbIM_UseAnyMods}
184 static LookupEntry groupComponentNames[] = {
185 {"base", XkbIM_UseBase}
187 {"latched", XkbIM_UseLatched}
189 {"locked", XkbIM_UseLocked}
191 {"effective", XkbIM_UseEffective}
193 {"any", XkbIM_UseAnyGroup}
201 SetIndicatorMapField(LEDInfo * led,
203 char *field, ExprDef * arrayNdx, ExprDef * value)
209 if ((uStrCaseCmp(field, "modifiers") == 0)
210 || (uStrCaseCmp(field, "mods") == 0))
212 if (arrayNdx != NULL)
213 return ReportIndicatorNotArray(led, field);
214 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (char *) xkb))
215 return ReportIndicatorBadType(led, field, "modifier mask");
216 led->real_mods = rtrn.uval & 0xff;
217 led->vmods = (rtrn.uval >> 8) & 0xff;
218 led->defs.defined |= _LED_Mods;
220 else if (uStrCaseCmp(field, "groups") == 0)
222 if (arrayNdx != NULL)
223 return ReportIndicatorNotArray(led, field);
225 (value, &rtrn, SimpleLookup, (char *) groupNames))
226 return ReportIndicatorBadType(led, field, "group mask");
227 led->groups = rtrn.uval;
228 led->defs.defined |= _LED_Groups;
230 else if ((uStrCaseCmp(field, "controls") == 0) ||
231 (uStrCaseCmp(field, "ctrls") == 0))
233 if (arrayNdx != NULL)
234 return ReportIndicatorNotArray(led, field);
236 (value, &rtrn, SimpleLookup, (char *) ctrlNames))
237 return ReportIndicatorBadType(led, field,
239 led->ctrls = rtrn.uval;
240 led->defs.defined |= _LED_Ctrls;
242 else if (uStrCaseCmp(field, "allowexplicit") == 0)
244 if (arrayNdx != NULL)
245 return ReportIndicatorNotArray(led, field);
246 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
247 return ReportIndicatorBadType(led, field, "boolean");
249 led->flags &= ~XkbIM_NoExplicit;
251 led->flags |= XkbIM_NoExplicit;
252 led->defs.defined |= _LED_Explicit;
254 else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
255 (uStrCaseCmp(field, "whichmodifierstate") == 0))
257 if (arrayNdx != NULL)
258 return ReportIndicatorNotArray(led, field);
259 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
260 (char *) modComponentNames))
262 return ReportIndicatorBadType(led, field,
263 "mask of modifier state components");
265 led->which_mods = rtrn.uval;
267 else if (uStrCaseCmp(field, "whichgroupstate") == 0)
269 if (arrayNdx != NULL)
270 return ReportIndicatorNotArray(led, field);
271 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
272 (char *) groupComponentNames))
274 return ReportIndicatorBadType(led, field,
275 "mask of group state components");
277 led->which_groups = rtrn.uval;
279 else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
280 (uStrCaseCmp(field, "driveskeyboard") == 0) ||
281 (uStrCaseCmp(field, "leddriveskbd") == 0) ||
282 (uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
283 (uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
284 (uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
286 if (arrayNdx != NULL)
287 return ReportIndicatorNotArray(led, field);
288 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
289 return ReportIndicatorBadType(led, field, "boolean");
291 led->flags |= XkbIM_LEDDrivesKB;
293 led->flags &= ~XkbIM_LEDDrivesKB;
294 led->defs.defined |= _LED_DrivesKbd;
296 else if (uStrCaseCmp(field, "index") == 0)
298 if (arrayNdx != NULL)
299 return ReportIndicatorNotArray(led, field);
300 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
301 return ReportIndicatorBadType(led, field,
303 if ((rtrn.uval < 1) || (rtrn.uval > 32))
305 ERROR("Illegal indicator index %d (range 1..%d)\n",
306 rtrn.uval, XkbNumIndicators);
307 ACTION("Index definition for %s indicator ignored\n",
308 XkbcAtomText(led->name));
311 led->indicator = rtrn.uval;
312 led->defs.defined |= _LED_Index;
316 ERROR("Unknown field %s in map for %s indicator\n", field,
317 XkbcAtomText(led->name));
318 ACTION("Definition ignored\n");
325 HandleIndicatorMapDef(IndicatorMapDef * def,
327 LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
333 if (def->merge != MergeDefault)
337 led.defs.merge = merge;
338 led.name = def->name;
341 for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
343 ExprResult elem, field;
345 if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
350 if (elem.str != NULL)
353 ("Cannot set defaults for \"%s\" element in indicator map\n",
355 ACTION("Assignment to %s.%s ignored\n", elem.str, field.str);
360 ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
368 rtrn = AddIndicatorMap(oldLEDs, &led);
375 CopyIndicatorMapDefs(XkbcDescPtr xkb, LEDInfo *leds, LEDInfo **unboundRtrn)
378 LEDInfo *unbound, *last;
380 if (XkbcAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
382 WSGO("Couldn't allocate names\n");
383 ACTION("Indicator names may be incorrect\n");
385 if (XkbcAllocIndicatorMaps(xkb) != Success)
387 WSGO("Can't allocate indicator maps\n");
388 ACTION("Indicator map definitions may be lost\n");
391 last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
392 while ((last != NULL) && (last->defs.next != NULL))
394 last = (LEDInfo *) last->defs.next;
396 for (led = leds; led != NULL; led = next)
398 next = (LEDInfo *) led->defs.next;
399 if ((led->groups != 0) && (led->which_groups == 0))
400 led->which_groups = XkbIM_UseEffective;
401 if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
402 led->which_mods = XkbIM_UseEffective;
403 if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
405 if (unboundRtrn != NULL)
407 led->defs.next = NULL;
409 last->defs.next = (CommonInfo *) led;
419 register XkbIndicatorMapPtr im;
420 im = &xkb->indicators->maps[led->indicator - 1];
421 im->flags = led->flags;
422 im->which_groups = led->which_groups;
423 im->groups = led->groups;
424 im->which_mods = led->which_mods;
425 im->mods.mask = led->real_mods;
426 im->mods.real_mods = led->real_mods;
427 im->mods.vmods = led->vmods;
428 im->ctrls = led->ctrls;
429 if (xkb->names != NULL)
430 xkb->names->indicators[led->indicator - 1] = led->name;
434 if (unboundRtrn != NULL)
436 *unboundRtrn = unbound;
442 BindIndicators(XkbcDescPtr xkb, Bool force, LEDInfo *unbound,
443 LEDInfo **unboundRtrn)
446 register LEDInfo *led, *next, *last;
448 if (xkb->names != NULL)
450 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
452 if (led->indicator == _LED_NotBound)
454 for (i = 0; i < XkbNumIndicators; i++)
456 if (xkb->names->indicators[i] == led->name)
458 led->indicator = i + 1;
466 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
468 if (led->indicator == _LED_NotBound)
470 for (i = 0; i < XkbNumIndicators; i++)
472 if (xkb->names->indicators[i] == None)
474 xkb->names->indicators[i] = led->name;
475 led->indicator = i + 1;
476 xkb->indicators->phys_indicators &= ~(1 << i);
480 if (led->indicator == _LED_NotBound)
482 ERROR("No unnamed indicators found\n");
484 ("Virtual indicator map \"%s\" not bound\n",
485 XkbcAtomText(led->name));
492 for (last = NULL, led = unbound; led != NULL; led = next)
494 next = (LEDInfo *) led->defs.next;
495 if (led->indicator == _LED_NotBound)
505 last->defs.next = &led->defs;
513 if ((xkb->names != NULL) &&
514 (xkb->names->indicators[led->indicator - 1] != led->name))
516 CARD32 old = xkb->names->indicators[led->indicator - 1];
517 ERROR("Multiple names bound to indicator %d\n",
518 (unsigned int) led->indicator);
519 ACTION("Using %s, ignoring %s\n",
521 XkbcAtomText(led->name));
522 led->indicator = _LED_NotBound;
531 last->defs.next = &led->defs;
539 XkbIndicatorMapPtr map;
540 map = &xkb->indicators->maps[led->indicator - 1];
541 map->flags = led->flags;
542 map->which_groups = led->which_groups;
543 map->groups = led->groups;
544 map->which_mods = led->which_mods;
545 map->mods.mask = led->real_mods;
546 map->mods.real_mods = led->real_mods;
547 map->mods.vmods = led->vmods;
548 map->ctrls = led->ctrls;
550 last->defs.next = &next->defs;
553 led->defs.next = NULL;
560 *unboundRtrn = unbound;
564 for (led = unbound; led != NULL; led = next)
566 next = (LEDInfo *) led->defs.next;