1f46a6179Smrg/************************************************************ 2f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3f46a6179Smrg 4f46a6179Smrg Permission to use, copy, modify, and distribute this 5f46a6179Smrg software and its documentation for any purpose and without 6f46a6179Smrg fee is hereby granted, provided that the above copyright 7f46a6179Smrg notice appear in all copies and that both that copyright 8f46a6179Smrg notice and this permission notice appear in supporting 9bfe6082cSmrg documentation, and that the name of Silicon Graphics not be 10bfe6082cSmrg used in advertising or publicity pertaining to distribution 11f46a6179Smrg of the software without specific prior written permission. 12bfe6082cSmrg Silicon Graphics makes no representation about the suitability 13f46a6179Smrg of this software for any purpose. It is provided "as is" 14f46a6179Smrg without any express or implied warranty. 15bfe6082cSmrg 16bfe6082cSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17bfe6082cSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19bfe6082cSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20bfe6082cSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21bfe6082cSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24f46a6179Smrg 25f46a6179Smrg ********************************************************/ 26f46a6179Smrg 27f46a6179Smrg#include "xkbcomp.h" 28f46a6179Smrg#include "misc.h" 29f46a6179Smrg#include "tokens.h" 30f46a6179Smrg#include "expr.h" 31f46a6179Smrg#include "vmod.h" 32f46a6179Smrg#include "indicators.h" 33f46a6179Smrg#include "action.h" 34f46a6179Smrg#include "compat.h" 35f46a6179Smrg 36f46a6179Smrg/***====================================================================***/ 37f46a6179Smrg 38f46a6179Smrg#define ReportIndicatorBadType(d,l,f,w) \ 39f46a6179Smrg ReportBadType("indicator map",(f),\ 40f46a6179Smrg XkbAtomText((d),(l)->name,XkbMessage),(w)) 41f46a6179Smrg#define ReportIndicatorNotArray(d,l,f) \ 42f46a6179Smrg ReportNotArray("indicator map",(f),\ 43f46a6179Smrg XkbAtomText((d),(l)->name,XkbMessage)) 44f46a6179Smrg 45f46a6179Smrg/***====================================================================***/ 46f46a6179Smrg 47f46a6179Smrgvoid 4834345a63SmrgClearIndicatorMapInfo(Display * dpy, LEDInfo * info) 49f46a6179Smrg{ 5034345a63Smrg info->name = XkbInternAtom(dpy, "default", False); 5134345a63Smrg info->indicator = _LED_NotBound; 5234345a63Smrg info->flags = info->which_mods = info->real_mods = 0; 5334345a63Smrg info->vmods = 0; 5434345a63Smrg info->which_groups = info->groups = 0; 5534345a63Smrg info->ctrls = 0; 56f46a6179Smrg return; 57f46a6179Smrg} 58f46a6179Smrg 59f46a6179SmrgLEDInfo * 606930ead5SmrgAddIndicatorMap(LEDInfo *oldLEDs, const LEDInfo *new) 61f46a6179Smrg{ 6234345a63Smrg LEDInfo *old, *last; 63f46a6179Smrg 6434345a63Smrg last = NULL; 6534345a63Smrg for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next) 6634345a63Smrg { 6734345a63Smrg if (old->name == new->name) 6834345a63Smrg { 696930ead5Smrg unsigned collide; 706930ead5Smrg 7134345a63Smrg if ((old->real_mods == new->real_mods) && 7234345a63Smrg (old->vmods == new->vmods) && 7334345a63Smrg (old->groups == new->groups) && 7434345a63Smrg (old->ctrls == new->ctrls) && 7534345a63Smrg (old->which_mods == new->which_mods) && 7634345a63Smrg (old->which_groups == new->which_groups)) 7734345a63Smrg { 7834345a63Smrg old->defs.defined |= new->defs.defined; 7934345a63Smrg return oldLEDs; 8034345a63Smrg } 8134345a63Smrg if (new->defs.merge == MergeReplace) 8234345a63Smrg { 8334345a63Smrg CommonInfo *next = old->defs.next; 8434345a63Smrg if (((old->defs.fileID == new->defs.fileID) 8534345a63Smrg && (warningLevel > 0)) || (warningLevel > 9)) 8634345a63Smrg { 87bfe6082cSmrg WARN("Map for indicator %s redefined\n", 8834345a63Smrg XkbAtomText(NULL, old->name, XkbMessage)); 8934345a63Smrg ACTION("Earlier definition ignored\n"); 9034345a63Smrg } 9134345a63Smrg *old = *new; 9234345a63Smrg old->defs.next = next; 9334345a63Smrg return oldLEDs; 9434345a63Smrg } 9534345a63Smrg collide = 0; 9634345a63Smrg if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide)) 9734345a63Smrg { 9834345a63Smrg old->indicator = new->indicator; 9934345a63Smrg old->defs.defined |= _LED_Index; 10034345a63Smrg } 10134345a63Smrg if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide)) 10234345a63Smrg { 10334345a63Smrg old->which_mods = new->which_mods; 10434345a63Smrg old->real_mods = new->real_mods; 10534345a63Smrg old->vmods = new->vmods; 10634345a63Smrg old->defs.defined |= _LED_Mods; 10734345a63Smrg } 10834345a63Smrg if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide)) 10934345a63Smrg { 11034345a63Smrg old->which_groups = new->which_groups; 11134345a63Smrg old->groups = new->groups; 11234345a63Smrg old->defs.defined |= _LED_Groups; 11334345a63Smrg } 11434345a63Smrg if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide)) 11534345a63Smrg { 11634345a63Smrg old->ctrls = new->ctrls; 11734345a63Smrg old->defs.defined |= _LED_Ctrls; 11834345a63Smrg } 11934345a63Smrg if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide)) 12034345a63Smrg { 12134345a63Smrg old->flags &= ~XkbIM_NoExplicit; 12234345a63Smrg old->flags |= (new->flags & XkbIM_NoExplicit); 12334345a63Smrg old->defs.defined |= _LED_Explicit; 12434345a63Smrg } 12534345a63Smrg if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide)) 12634345a63Smrg { 12734345a63Smrg old->flags &= ~XkbIM_NoAutomatic; 12834345a63Smrg old->flags |= (new->flags & XkbIM_NoAutomatic); 12934345a63Smrg old->defs.defined |= _LED_Automatic; 13034345a63Smrg } 13134345a63Smrg if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide)) 13234345a63Smrg { 13334345a63Smrg old->flags &= ~XkbIM_LEDDrivesKB; 13434345a63Smrg old->flags |= (new->flags & XkbIM_LEDDrivesKB); 13534345a63Smrg old->defs.defined |= _LED_DrivesKbd; 13634345a63Smrg } 137a57d84feSmrg if (collide && (warningLevel > 0)) 13834345a63Smrg { 139bfe6082cSmrg WARN("Map for indicator %s redefined\n", 14034345a63Smrg XkbAtomText(NULL, old->name, XkbMessage)); 141bfe6082cSmrg ACTION("Using %s definition for duplicate fields\n", 14234345a63Smrg (new->defs.merge == MergeAugment ? "first" : "last")); 14334345a63Smrg } 14434345a63Smrg return oldLEDs; 14534345a63Smrg } 14634345a63Smrg if (old->defs.next == NULL) 14734345a63Smrg last = old; 148f46a6179Smrg } 149f46a6179Smrg /* new definition */ 1506930ead5Smrg old = malloc(sizeof(LEDInfo)); 15134345a63Smrg if (!old) 15234345a63Smrg { 15334345a63Smrg WSGO("Couldn't allocate indicator map\n"); 154bfe6082cSmrg ACTION("Map for indicator %s not compiled\n", 15534345a63Smrg XkbAtomText(NULL, new->name, XkbMessage)); 15634345a63Smrg return NULL; 157f46a6179Smrg } 15834345a63Smrg *old = *new; 15934345a63Smrg old->defs.next = NULL; 16034345a63Smrg if (last) 16134345a63Smrg { 16234345a63Smrg last->defs.next = &old->defs; 16334345a63Smrg return oldLEDs; 164f46a6179Smrg } 165f46a6179Smrg return old; 166f46a6179Smrg} 167f46a6179Smrg 16834345a63Smrgstatic LookupEntry modComponentNames[] = { 16934345a63Smrg {"base", XkbIM_UseBase} 17034345a63Smrg , 17134345a63Smrg {"latched", XkbIM_UseLatched} 17234345a63Smrg , 17334345a63Smrg {"locked", XkbIM_UseLocked} 17434345a63Smrg , 17534345a63Smrg {"effective", XkbIM_UseEffective} 17634345a63Smrg , 17734345a63Smrg {"compat", XkbIM_UseCompat} 17834345a63Smrg , 17934345a63Smrg {"any", XkbIM_UseAnyMods} 18034345a63Smrg , 18134345a63Smrg {"none", 0} 18234345a63Smrg , 18334345a63Smrg {NULL, 0} 184f46a6179Smrg}; 18534345a63Smrgstatic LookupEntry groupComponentNames[] = { 18634345a63Smrg {"base", XkbIM_UseBase} 18734345a63Smrg , 18834345a63Smrg {"latched", XkbIM_UseLatched} 18934345a63Smrg , 19034345a63Smrg {"locked", XkbIM_UseLocked} 19134345a63Smrg , 19234345a63Smrg {"effective", XkbIM_UseEffective} 19334345a63Smrg , 19434345a63Smrg {"any", XkbIM_UseAnyGroup} 19534345a63Smrg , 19634345a63Smrg {"none", 0} 19734345a63Smrg , 19834345a63Smrg {NULL, 0} 199f46a6179Smrg}; 200f46a6179Smrg 201f46a6179Smrgint 2026930ead5SmrgSetIndicatorMapField(LEDInfo *led, XkbDescPtr xkb, const char *field, 2036930ead5Smrg const ExprDef *arrayNdx, const ExprDef *value) 204f46a6179Smrg{ 20534345a63Smrg ExprResult rtrn; 20634345a63Smrg Bool ok; 207f46a6179Smrg 20834345a63Smrg ok = True; 20934345a63Smrg if ((uStrCaseCmp(field, "modifiers") == 0) 21034345a63Smrg || (uStrCaseCmp(field, "mods") == 0)) 21134345a63Smrg { 21234345a63Smrg if (arrayNdx != NULL) 21334345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 21434345a63Smrg if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb)) 21534345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, 21634345a63Smrg "modifier mask"); 21734345a63Smrg led->real_mods = rtrn.uval & 0xff; 21834345a63Smrg led->vmods = (rtrn.uval >> 8) & 0xff; 21934345a63Smrg led->defs.defined |= _LED_Mods; 220f46a6179Smrg } 22134345a63Smrg else if (uStrCaseCmp(field, "groups") == 0) 22234345a63Smrg { 22334345a63Smrg if (arrayNdx != NULL) 22434345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 22534345a63Smrg if (!ExprResolveMask 22634345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) groupNames)) 22734345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, "group mask"); 22834345a63Smrg led->groups = rtrn.uval; 22934345a63Smrg led->defs.defined |= _LED_Groups; 230f46a6179Smrg } 23134345a63Smrg else if ((uStrCaseCmp(field, "controls") == 0) || 23234345a63Smrg (uStrCaseCmp(field, "ctrls") == 0)) 23334345a63Smrg { 23434345a63Smrg if (arrayNdx != NULL) 23534345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 23634345a63Smrg if (!ExprResolveMask 23734345a63Smrg (value, &rtrn, SimpleLookup, (XPointer) ctrlNames)) 23834345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, 23934345a63Smrg "controls mask"); 24034345a63Smrg led->ctrls = rtrn.uval; 24134345a63Smrg led->defs.defined |= _LED_Ctrls; 242f46a6179Smrg } 24334345a63Smrg else if (uStrCaseCmp(field, "allowexplicit") == 0) 24434345a63Smrg { 24534345a63Smrg if (arrayNdx != NULL) 24634345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 24734345a63Smrg if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) 24834345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, "boolean"); 24934345a63Smrg if (rtrn.uval) 25034345a63Smrg led->flags &= ~XkbIM_NoExplicit; 25134345a63Smrg else 25234345a63Smrg led->flags |= XkbIM_NoExplicit; 25334345a63Smrg led->defs.defined |= _LED_Explicit; 254f46a6179Smrg } 25534345a63Smrg else if ((uStrCaseCmp(field, "whichmodstate") == 0) || 25634345a63Smrg (uStrCaseCmp(field, "whichmodifierstate") == 0)) 25734345a63Smrg { 25834345a63Smrg if (arrayNdx != NULL) 25934345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 26034345a63Smrg if (!ExprResolveMask(value, &rtrn, SimpleLookup, 26134345a63Smrg (XPointer) modComponentNames)) 26234345a63Smrg { 26334345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, 26434345a63Smrg "mask of modifier state components"); 26534345a63Smrg } 26634345a63Smrg led->which_mods = rtrn.uval; 267f46a6179Smrg } 26834345a63Smrg else if (uStrCaseCmp(field, "whichgroupstate") == 0) 26934345a63Smrg { 27034345a63Smrg if (arrayNdx != NULL) 27134345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 27234345a63Smrg if (!ExprResolveMask(value, &rtrn, SimpleLookup, 27334345a63Smrg (XPointer) groupComponentNames)) 27434345a63Smrg { 27534345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, 27634345a63Smrg "mask of group state components"); 27734345a63Smrg } 27834345a63Smrg led->which_groups = rtrn.uval; 279f46a6179Smrg } 28034345a63Smrg else if ((uStrCaseCmp(field, "driveskbd") == 0) || 28134345a63Smrg (uStrCaseCmp(field, "driveskeyboard") == 0) || 28234345a63Smrg (uStrCaseCmp(field, "leddriveskbd") == 0) || 28334345a63Smrg (uStrCaseCmp(field, "leddriveskeyboard") == 0) || 28434345a63Smrg (uStrCaseCmp(field, "indicatordriveskbd") == 0) || 28534345a63Smrg (uStrCaseCmp(field, "indicatordriveskeyboard") == 0)) 28634345a63Smrg { 28734345a63Smrg if (arrayNdx != NULL) 28834345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 28934345a63Smrg if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) 29034345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, "boolean"); 29134345a63Smrg if (rtrn.uval) 29234345a63Smrg led->flags |= XkbIM_LEDDrivesKB; 29334345a63Smrg else 29434345a63Smrg led->flags &= ~XkbIM_LEDDrivesKB; 29534345a63Smrg led->defs.defined |= _LED_DrivesKbd; 296f46a6179Smrg } 29734345a63Smrg else if (uStrCaseCmp(field, "index") == 0) 29834345a63Smrg { 29934345a63Smrg if (arrayNdx != NULL) 30034345a63Smrg return ReportIndicatorNotArray(xkb->dpy, led, field); 30134345a63Smrg if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) 30234345a63Smrg return ReportIndicatorBadType(xkb->dpy, led, field, 30334345a63Smrg "indicator index"); 30434345a63Smrg if ((rtrn.uval < 1) || (rtrn.uval > 32)) 30534345a63Smrg { 306bfe6082cSmrg ERROR("Illegal indicator index %d (range 1..%d)\n", 30734345a63Smrg rtrn.uval, XkbNumIndicators); 308bfe6082cSmrg ACTION("Index definition for %s indicator ignored\n", 30934345a63Smrg XkbAtomText(NULL, led->name, XkbMessage)); 31034345a63Smrg return False; 31134345a63Smrg } 31234345a63Smrg led->indicator = rtrn.uval; 31334345a63Smrg led->defs.defined |= _LED_Index; 31434345a63Smrg } 31534345a63Smrg else 31634345a63Smrg { 317bfe6082cSmrg ERROR("Unknown field %s in map for %s indicator\n", field, 31834345a63Smrg XkbAtomText(NULL, led->name, XkbMessage)); 31934345a63Smrg ACTION("Definition ignored\n"); 32034345a63Smrg ok = False; 321f46a6179Smrg } 322f46a6179Smrg return ok; 323f46a6179Smrg} 324f46a6179Smrg 325f46a6179SmrgLEDInfo * 3266930ead5SmrgHandleIndicatorMapDef(IndicatorMapDef *def, XkbDescPtr xkb, 3276930ead5Smrg const LEDInfo *dflt, LEDInfo *oldLEDs, unsigned merge) 328f46a6179Smrg{ 3296930ead5Smrg LEDInfo led; 33034345a63Smrg Bool ok; 331f46a6179Smrg 33234345a63Smrg if (def->merge != MergeDefault) 33334345a63Smrg merge = def->merge; 334f46a6179Smrg 33534345a63Smrg led = *dflt; 33634345a63Smrg led.defs.merge = merge; 33734345a63Smrg led.name = def->name; 33834345a63Smrg 33934345a63Smrg ok = True; 3406930ead5Smrg for (VarDef *var = def->body; var != NULL; 3416930ead5Smrg var = (VarDef *) var->common.next) 34234345a63Smrg { 34334345a63Smrg ExprResult elem, field; 34434345a63Smrg ExprDef *arrayNdx; 34534345a63Smrg if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx)) 34634345a63Smrg { 34734345a63Smrg ok = False; 34834345a63Smrg continue; 34934345a63Smrg } 35034345a63Smrg if (elem.str != NULL) 35134345a63Smrg { 352bfe6082cSmrg ERROR 35334345a63Smrg ("Cannot set defaults for \"%s\" element in indicator map\n", 35434345a63Smrg elem.str); 355bfe6082cSmrg ACTION("Assignment to %s.%s ignored\n", elem.str, field.str); 35634345a63Smrg ok = False; 35734345a63Smrg } 35834345a63Smrg else 35934345a63Smrg { 36034345a63Smrg ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx, 36134345a63Smrg var->value) && ok; 36234345a63Smrg } 363f46a6179Smrg } 36434345a63Smrg if (ok) 36534345a63Smrg { 3666930ead5Smrg LEDInfo *rtrn = AddIndicatorMap(oldLEDs, &led); 36734345a63Smrg return rtrn; 368f46a6179Smrg } 369f46a6179Smrg return NULL; 370f46a6179Smrg} 371f46a6179Smrg 37234345a63SmrgBool 37334345a63SmrgCopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds, 37434345a63Smrg LEDInfo ** unboundRtrn) 375f46a6179Smrg{ 37634345a63Smrg LEDInfo *led, *next; 37734345a63Smrg LEDInfo *unbound, *last; 37834345a63Smrg XkbDescPtr xkb; 379f46a6179Smrg 38034345a63Smrg xkb = result->xkb; 38134345a63Smrg if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success) 38234345a63Smrg { 38334345a63Smrg WSGO("Couldn't allocate names\n"); 38434345a63Smrg ACTION("Indicator names may be incorrect\n"); 385f46a6179Smrg } 38634345a63Smrg if (XkbAllocIndicatorMaps(xkb) != Success) 38734345a63Smrg { 38834345a63Smrg WSGO("Can't allocate indicator maps\n"); 38934345a63Smrg ACTION("Indicator map definitions may be lost\n"); 39034345a63Smrg return False; 391f46a6179Smrg } 39234345a63Smrg last = unbound = (unboundRtrn ? *unboundRtrn : NULL); 39334345a63Smrg while ((last != NULL) && (last->defs.next != NULL)) 39434345a63Smrg { 39534345a63Smrg last = (LEDInfo *) last->defs.next; 396f46a6179Smrg } 39734345a63Smrg for (led = leds; led != NULL; led = next) 39834345a63Smrg { 39934345a63Smrg next = (LEDInfo *) led->defs.next; 40034345a63Smrg if ((led->groups != 0) && (led->which_groups == 0)) 40134345a63Smrg led->which_groups = XkbIM_UseEffective; 40234345a63Smrg if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods))) 40334345a63Smrg led->which_mods = XkbIM_UseEffective; 40434345a63Smrg if ((led->indicator == _LED_NotBound) || (!xkb->indicators)) 40534345a63Smrg { 40634345a63Smrg if (unboundRtrn != NULL) 40734345a63Smrg { 40834345a63Smrg led->defs.next = NULL; 40934345a63Smrg if (last != NULL) 41034345a63Smrg last->defs.next = (CommonInfo *) led; 41134345a63Smrg else 41234345a63Smrg unbound = led; 41334345a63Smrg last = led; 41434345a63Smrg } 41534345a63Smrg else 4166930ead5Smrg free(led); 41734345a63Smrg } 41834345a63Smrg else 41934345a63Smrg { 4206930ead5Smrg XkbIndicatorMapPtr im; 42134345a63Smrg im = &xkb->indicators->maps[led->indicator - 1]; 42234345a63Smrg im->flags = led->flags; 42334345a63Smrg im->which_groups = led->which_groups; 42434345a63Smrg im->groups = led->groups; 42534345a63Smrg im->which_mods = led->which_mods; 42634345a63Smrg im->mods.mask = led->real_mods; 42734345a63Smrg im->mods.real_mods = led->real_mods; 42834345a63Smrg im->mods.vmods = led->vmods; 42934345a63Smrg im->ctrls = led->ctrls; 43034345a63Smrg if (xkb->names != NULL) 43134345a63Smrg xkb->names->indicators[led->indicator - 1] = led->name; 4326930ead5Smrg free(led); 43334345a63Smrg } 434f46a6179Smrg } 43534345a63Smrg if (unboundRtrn != NULL) 43634345a63Smrg { 43734345a63Smrg *unboundRtrn = unbound; 438f46a6179Smrg } 439f46a6179Smrg return True; 440f46a6179Smrg} 441f46a6179Smrg 442f46a6179SmrgBool 44334345a63SmrgBindIndicators(XkbFileInfo * result, 44434345a63Smrg Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn) 445f46a6179Smrg{ 44634345a63Smrg XkbDescPtr xkb; 4476930ead5Smrg LEDInfo *led, *next, *last; 448f46a6179Smrg 44934345a63Smrg xkb = result->xkb; 45034345a63Smrg if (xkb->names != NULL) 45134345a63Smrg { 45234345a63Smrg for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) 45334345a63Smrg { 45434345a63Smrg if (led->indicator == _LED_NotBound) 45534345a63Smrg { 4566930ead5Smrg for (int i = 0; i < XkbNumIndicators; i++) 45734345a63Smrg { 45834345a63Smrg if (xkb->names->indicators[i] == led->name) 45934345a63Smrg { 46034345a63Smrg led->indicator = i + 1; 46134345a63Smrg break; 46234345a63Smrg } 46334345a63Smrg } 46434345a63Smrg } 46534345a63Smrg } 46634345a63Smrg if (force) 46734345a63Smrg { 46834345a63Smrg for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) 46934345a63Smrg { 47034345a63Smrg if (led->indicator == _LED_NotBound) 47134345a63Smrg { 4726930ead5Smrg for (int i = 0; i < XkbNumIndicators; i++) 47334345a63Smrg { 47434345a63Smrg if (xkb->names->indicators[i] == None) 47534345a63Smrg { 47634345a63Smrg xkb->names->indicators[i] = led->name; 47734345a63Smrg led->indicator = i + 1; 47834345a63Smrg xkb->indicators->phys_indicators &= ~(1 << i); 47934345a63Smrg break; 48034345a63Smrg } 48134345a63Smrg } 48234345a63Smrg if (led->indicator == _LED_NotBound) 48334345a63Smrg { 48434345a63Smrg ERROR("No unnamed indicators found\n"); 485bfe6082cSmrg ACTION 48634345a63Smrg ("Virtual indicator map \"%s\" not bound\n", 48734345a63Smrg XkbAtomGetString(xkb->dpy, led->name)); 48834345a63Smrg continue; 48934345a63Smrg } 49034345a63Smrg } 49134345a63Smrg } 49234345a63Smrg } 493f46a6179Smrg } 49434345a63Smrg for (last = NULL, led = unbound; led != NULL; led = next) 49534345a63Smrg { 49634345a63Smrg next = (LEDInfo *) led->defs.next; 49734345a63Smrg if (led->indicator == _LED_NotBound) 49834345a63Smrg { 49934345a63Smrg if (force) 50034345a63Smrg { 50134345a63Smrg unbound = next; 5026930ead5Smrg free(led); 50334345a63Smrg } 50434345a63Smrg else 50534345a63Smrg { 50634345a63Smrg if (last) 50734345a63Smrg last->defs.next = &led->defs; 50834345a63Smrg else 50934345a63Smrg unbound = led; 51034345a63Smrg last = led; 51134345a63Smrg } 51234345a63Smrg } 51334345a63Smrg else 51434345a63Smrg { 51534345a63Smrg if ((xkb->names != NULL) && 51634345a63Smrg (xkb->names->indicators[led->indicator - 1] != led->name)) 51734345a63Smrg { 51834345a63Smrg Atom old = xkb->names->indicators[led->indicator - 1]; 519bfe6082cSmrg ERROR("Multiple names bound to indicator %d\n", 52034345a63Smrg (unsigned int) led->indicator); 521bfe6082cSmrg ACTION("Using %s, ignoring %s\n", 52234345a63Smrg XkbAtomGetString(xkb->dpy, old), 52334345a63Smrg XkbAtomGetString(xkb->dpy, led->name)); 52434345a63Smrg led->indicator = _LED_NotBound; 52534345a63Smrg if (force) 52634345a63Smrg { 5276930ead5Smrg free(led); 52834345a63Smrg unbound = next; 52934345a63Smrg } 53034345a63Smrg else 53134345a63Smrg { 53234345a63Smrg if (last) 53334345a63Smrg last->defs.next = &led->defs; 53434345a63Smrg else 53534345a63Smrg unbound = led; 53634345a63Smrg last = led; 53734345a63Smrg } 53834345a63Smrg } 53934345a63Smrg else 54034345a63Smrg { 54134345a63Smrg XkbIndicatorMapPtr map; 54234345a63Smrg map = &xkb->indicators->maps[led->indicator - 1]; 54334345a63Smrg map->flags = led->flags; 54434345a63Smrg map->which_groups = led->which_groups; 54534345a63Smrg map->groups = led->groups; 54634345a63Smrg map->which_mods = led->which_mods; 54734345a63Smrg map->mods.mask = led->real_mods; 54834345a63Smrg map->mods.real_mods = led->real_mods; 54934345a63Smrg map->mods.vmods = led->vmods; 55034345a63Smrg map->ctrls = led->ctrls; 55134345a63Smrg if (last) 55234345a63Smrg last->defs.next = &next->defs; 55334345a63Smrg else 55434345a63Smrg unbound = next; 55534345a63Smrg led->defs.next = NULL; 5566930ead5Smrg free(led); 55734345a63Smrg } 55834345a63Smrg } 559f46a6179Smrg } 56034345a63Smrg if (unboundRtrn) 56134345a63Smrg { 56234345a63Smrg *unboundRtrn = unbound; 563f46a6179Smrg } 56434345a63Smrg else if (unbound) 56534345a63Smrg { 56634345a63Smrg for (led = unbound; led != NULL; led = next) 56734345a63Smrg { 56834345a63Smrg next = (LEDInfo *) led->defs.next; 5696930ead5Smrg free(led); 57034345a63Smrg } 571f46a6179Smrg } 572f46a6179Smrg return True; 573f46a6179Smrg} 574