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(d,l,f,w) \
39 ReportBadType("indicator map",(f),\
40 XkbAtomText((d),(l)->name,XkbMessage),(w))
41 #define ReportIndicatorNotArray(d,l,f) \
42 ReportNotArray("indicator map",(f),\
43 XkbAtomText((d),(l)->name,XkbMessage))
45 /***====================================================================***/
48 ClearIndicatorMapInfo(Display * dpy, LEDInfo * info)
50 info->name = XkbInternAtom(dpy, "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 WARN1("Map for indicator %s redefined\n",
87 XkbAtomText(NULL, old->name, XkbMessage));
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 WARN1("Map for indicator %s redefined\n",
139 XkbAtomText(NULL, old->name, XkbMessage));
140 ACTION1("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 ACTION1("Map for indicator %s not compiled\n",
154 XkbAtomText(NULL, new->name, XkbMessage));
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(xkb->dpy, led, field);
214 if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
215 return ReportIndicatorBadType(xkb->dpy, led, field,
217 led->real_mods = rtrn.uval & 0xff;
218 led->vmods = (rtrn.uval >> 8) & 0xff;
219 led->defs.defined |= _LED_Mods;
221 else if (uStrCaseCmp(field, "groups") == 0)
223 if (arrayNdx != NULL)
224 return ReportIndicatorNotArray(xkb->dpy, led, field);
226 (value, &rtrn, SimpleLookup, (XPointer) groupNames))
227 return ReportIndicatorBadType(xkb->dpy, led, field, "group mask");
228 led->groups = rtrn.uval;
229 led->defs.defined |= _LED_Groups;
231 else if ((uStrCaseCmp(field, "controls") == 0) ||
232 (uStrCaseCmp(field, "ctrls") == 0))
234 if (arrayNdx != NULL)
235 return ReportIndicatorNotArray(xkb->dpy, led, field);
237 (value, &rtrn, SimpleLookup, (XPointer) ctrlNames))
238 return ReportIndicatorBadType(xkb->dpy, led, field,
240 led->ctrls = rtrn.uval;
241 led->defs.defined |= _LED_Ctrls;
243 else if (uStrCaseCmp(field, "allowexplicit") == 0)
245 if (arrayNdx != NULL)
246 return ReportIndicatorNotArray(xkb->dpy, led, field);
247 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
248 return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
250 led->flags &= ~XkbIM_NoExplicit;
252 led->flags |= XkbIM_NoExplicit;
253 led->defs.defined |= _LED_Explicit;
255 else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
256 (uStrCaseCmp(field, "whichmodifierstate") == 0))
258 if (arrayNdx != NULL)
259 return ReportIndicatorNotArray(xkb->dpy, led, field);
260 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
261 (XPointer) modComponentNames))
263 return ReportIndicatorBadType(xkb->dpy, led, field,
264 "mask of modifier state components");
266 led->which_mods = rtrn.uval;
268 else if (uStrCaseCmp(field, "whichgroupstate") == 0)
270 if (arrayNdx != NULL)
271 return ReportIndicatorNotArray(xkb->dpy, led, field);
272 if (!ExprResolveMask(value, &rtrn, SimpleLookup,
273 (XPointer) groupComponentNames))
275 return ReportIndicatorBadType(xkb->dpy, led, field,
276 "mask of group state components");
278 led->which_groups = rtrn.uval;
280 else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
281 (uStrCaseCmp(field, "driveskeyboard") == 0) ||
282 (uStrCaseCmp(field, "leddriveskbd") == 0) ||
283 (uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
284 (uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
285 (uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
287 if (arrayNdx != NULL)
288 return ReportIndicatorNotArray(xkb->dpy, led, field);
289 if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
290 return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
292 led->flags |= XkbIM_LEDDrivesKB;
294 led->flags &= ~XkbIM_LEDDrivesKB;
295 led->defs.defined |= _LED_DrivesKbd;
297 else if (uStrCaseCmp(field, "index") == 0)
299 if (arrayNdx != NULL)
300 return ReportIndicatorNotArray(xkb->dpy, led, field);
301 if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
302 return ReportIndicatorBadType(xkb->dpy, led, field,
304 if ((rtrn.uval < 1) || (rtrn.uval > 32))
306 ERROR2("Illegal indicator index %d (range 1..%d)\n",
307 rtrn.uval, XkbNumIndicators);
308 ACTION1("Index definition for %s indicator ignored\n",
309 XkbAtomText(NULL, led->name, XkbMessage));
312 led->indicator = rtrn.uval;
313 led->defs.defined |= _LED_Index;
317 ERROR2("Unknown field %s in map for %s indicator\n", field,
318 XkbAtomText(NULL, led->name, XkbMessage));
319 ACTION("Definition ignored\n");
326 HandleIndicatorMapDef(IndicatorMapDef * def,
328 LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
334 if (def->merge != MergeDefault)
338 led.defs.merge = merge;
339 led.name = def->name;
342 for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
344 ExprResult elem, field;
346 if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
351 if (elem.str != NULL)
354 ("Cannot set defaults for \"%s\" element in indicator map\n",
356 ACTION2("Assignment to %s.%s ignored\n", elem.str, field.str);
361 ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
367 rtrn = AddIndicatorMap(oldLEDs, &led);
374 CopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds,
375 LEDInfo ** unboundRtrn)
378 LEDInfo *unbound, *last;
382 if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
384 WSGO("Couldn't allocate names\n");
385 ACTION("Indicator names may be incorrect\n");
387 if (XkbAllocIndicatorMaps(xkb) != Success)
389 WSGO("Can't allocate indicator maps\n");
390 ACTION("Indicator map definitions may be lost\n");
393 last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
394 while ((last != NULL) && (last->defs.next != NULL))
396 last = (LEDInfo *) last->defs.next;
398 for (led = leds; led != NULL; led = next)
400 next = (LEDInfo *) led->defs.next;
401 if ((led->groups != 0) && (led->which_groups == 0))
402 led->which_groups = XkbIM_UseEffective;
403 if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
404 led->which_mods = XkbIM_UseEffective;
405 if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
407 if (unboundRtrn != NULL)
409 led->defs.next = NULL;
411 last->defs.next = (CommonInfo *) led;
421 register XkbIndicatorMapPtr im;
422 im = &xkb->indicators->maps[led->indicator - 1];
423 im->flags = led->flags;
424 im->which_groups = led->which_groups;
425 im->groups = led->groups;
426 im->which_mods = led->which_mods;
427 im->mods.mask = led->real_mods;
428 im->mods.real_mods = led->real_mods;
429 im->mods.vmods = led->vmods;
430 im->ctrls = led->ctrls;
431 if (xkb->names != NULL)
432 xkb->names->indicators[led->indicator - 1] = led->name;
436 if (unboundRtrn != NULL)
438 *unboundRtrn = unbound;
444 BindIndicators(XkbFileInfo * result,
445 Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn)
449 register LEDInfo *led, *next, *last;
452 if (xkb->names != NULL)
454 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
456 if (led->indicator == _LED_NotBound)
458 for (i = 0; i < XkbNumIndicators; i++)
460 if (xkb->names->indicators[i] == led->name)
462 led->indicator = i + 1;
470 for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
472 if (led->indicator == _LED_NotBound)
474 for (i = 0; i < XkbNumIndicators; i++)
476 if (xkb->names->indicators[i] == None)
478 xkb->names->indicators[i] = led->name;
479 led->indicator = i + 1;
480 xkb->indicators->phys_indicators &= ~(1 << i);
484 if (led->indicator == _LED_NotBound)
486 ERROR("No unnamed indicators found\n");
488 ("Virtual indicator map \"%s\" not bound\n",
489 XkbAtomGetString(xkb->dpy, led->name));
496 for (last = NULL, led = unbound; led != NULL; led = next)
498 next = (LEDInfo *) led->defs.next;
499 if (led->indicator == _LED_NotBound)
509 last->defs.next = &led->defs;
517 if ((xkb->names != NULL) &&
518 (xkb->names->indicators[led->indicator - 1] != led->name))
520 Atom old = xkb->names->indicators[led->indicator - 1];
521 ERROR1("Multiple names bound to indicator %d\n",
522 (unsigned int) led->indicator);
523 ACTION2("Using %s, ignoring %s\n",
524 XkbAtomGetString(xkb->dpy, old),
525 XkbAtomGetString(xkb->dpy, led->name));
526 led->indicator = _LED_NotBound;
535 last->defs.next = &led->defs;
543 XkbIndicatorMapPtr map;
544 map = &xkb->indicators->maps[led->indicator - 1];
545 map->flags = led->flags;
546 map->which_groups = led->which_groups;
547 map->groups = led->groups;
548 map->which_mods = led->which_mods;
549 map->mods.mask = led->real_mods;
550 map->mods.real_mods = led->real_mods;
551 map->mods.vmods = led->vmods;
552 map->ctrls = led->ctrls;
554 last->defs.next = &next->defs;
557 led->defs.next = NULL;
564 *unboundRtrn = unbound;
568 for (led = unbound; led != NULL; led = next)
570 next = (LEDInfo *) led->defs.next;