indicators.c revision a57d84fe
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 * 6034345a63SmrgAddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new) 61f46a6179Smrg{ 6234345a63Smrg LEDInfo *old, *last; 6334345a63Smrg unsigned collide; 64f46a6179Smrg 6534345a63Smrg last = NULL; 6634345a63Smrg for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next) 6734345a63Smrg { 6834345a63Smrg if (old->name == new->name) 6934345a63Smrg { 7034345a63Smrg if ((old->real_mods == new->real_mods) && 7134345a63Smrg (old->vmods == new->vmods) && 7234345a63Smrg (old->groups == new->groups) && 7334345a63Smrg (old->ctrls == new->ctrls) && 7434345a63Smrg (old->which_mods == new->which_mods) && 7534345a63Smrg (old->which_groups == new->which_groups)) 7634345a63Smrg { 7734345a63Smrg old->defs.defined |= new->defs.defined; 7834345a63Smrg return oldLEDs; 7934345a63Smrg } 8034345a63Smrg if (new->defs.merge == MergeReplace) 8134345a63Smrg { 8234345a63Smrg CommonInfo *next = old->defs.next; 8334345a63Smrg if (((old->defs.fileID == new->defs.fileID) 8434345a63Smrg && (warningLevel > 0)) || (warningLevel > 9)) 8534345a63Smrg { 86bfe6082cSmrg WARN("Map for indicator %s redefined\n", 8734345a63Smrg XkbAtomText(NULL, old->name, XkbMessage)); 8834345a63Smrg ACTION("Earlier definition ignored\n"); 8934345a63Smrg } 9034345a63Smrg *old = *new; 9134345a63Smrg old->defs.next = next; 9234345a63Smrg return oldLEDs; 9334345a63Smrg } 9434345a63Smrg collide = 0; 9534345a63Smrg if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide)) 9634345a63Smrg { 9734345a63Smrg old->indicator = new->indicator; 9834345a63Smrg old->defs.defined |= _LED_Index; 9934345a63Smrg } 10034345a63Smrg if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide)) 10134345a63Smrg { 10234345a63Smrg old->which_mods = new->which_mods; 10334345a63Smrg old->real_mods = new->real_mods; 10434345a63Smrg old->vmods = new->vmods; 10534345a63Smrg old->defs.defined |= _LED_Mods; 10634345a63Smrg } 10734345a63Smrg if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide)) 10834345a63Smrg { 10934345a63Smrg old->which_groups = new->which_groups; 11034345a63Smrg old->groups = new->groups; 11134345a63Smrg old->defs.defined |= _LED_Groups; 11234345a63Smrg } 11334345a63Smrg if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide)) 11434345a63Smrg { 11534345a63Smrg old->ctrls = new->ctrls; 11634345a63Smrg old->defs.defined |= _LED_Ctrls; 11734345a63Smrg } 11834345a63Smrg if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide)) 11934345a63Smrg { 12034345a63Smrg old->flags &= ~XkbIM_NoExplicit; 12134345a63Smrg old->flags |= (new->flags & XkbIM_NoExplicit); 12234345a63Smrg old->defs.defined |= _LED_Explicit; 12334345a63Smrg } 12434345a63Smrg if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide)) 12534345a63Smrg { 12634345a63Smrg old->flags &= ~XkbIM_NoAutomatic; 12734345a63Smrg old->flags |= (new->flags & XkbIM_NoAutomatic); 12834345a63Smrg old->defs.defined |= _LED_Automatic; 12934345a63Smrg } 13034345a63Smrg if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide)) 13134345a63Smrg { 13234345a63Smrg old->flags &= ~XkbIM_LEDDrivesKB; 13334345a63Smrg old->flags |= (new->flags & XkbIM_LEDDrivesKB); 13434345a63Smrg old->defs.defined |= _LED_DrivesKbd; 13534345a63Smrg } 136a57d84feSmrg if (collide && (warningLevel > 0)) 13734345a63Smrg { 138bfe6082cSmrg WARN("Map for indicator %s redefined\n", 13934345a63Smrg XkbAtomText(NULL, old->name, XkbMessage)); 140bfe6082cSmrg ACTION("Using %s definition for duplicate fields\n", 14134345a63Smrg (new->defs.merge == MergeAugment ? "first" : "last")); 14234345a63Smrg } 14334345a63Smrg return oldLEDs; 14434345a63Smrg } 14534345a63Smrg if (old->defs.next == NULL) 14634345a63Smrg last = old; 147f46a6179Smrg } 148f46a6179Smrg /* new definition */ 14934345a63Smrg old = uTypedAlloc(LEDInfo); 15034345a63Smrg if (!old) 15134345a63Smrg { 15234345a63Smrg WSGO("Couldn't allocate indicator map\n"); 153bfe6082cSmrg ACTION("Map for indicator %s not compiled\n", 15434345a63Smrg XkbAtomText(NULL, new->name, XkbMessage)); 15534345a63Smrg return NULL; 156f46a6179Smrg } 15734345a63Smrg *old = *new; 15834345a63Smrg old->defs.next = NULL; 15934345a63Smrg if (last) 16034345a63Smrg { 16134345a63Smrg last->defs.next = &old->defs; 16234345a63Smrg return oldLEDs; 163f46a6179Smrg } 164f46a6179Smrg return old; 165f46a6179Smrg} 166f46a6179Smrg 16734345a63Smrgstatic LookupEntry modComponentNames[] = { 16834345a63Smrg {"base", XkbIM_UseBase} 16934345a63Smrg , 17034345a63Smrg {"latched", XkbIM_UseLatched} 17134345a63Smrg , 17234345a63Smrg {"locked", XkbIM_UseLocked} 17334345a63Smrg , 17434345a63Smrg {"effective", XkbIM_UseEffective} 17534345a63Smrg , 17634345a63Smrg {"compat", XkbIM_UseCompat} 17734345a63Smrg , 17834345a63Smrg {"any", XkbIM_UseAnyMods} 17934345a63Smrg , 18034345a63Smrg {"none", 0} 18134345a63Smrg , 18234345a63Smrg {NULL, 0} 183f46a6179Smrg}; 18434345a63Smrgstatic LookupEntry groupComponentNames[] = { 18534345a63Smrg {"base", XkbIM_UseBase} 18634345a63Smrg , 18734345a63Smrg {"latched", XkbIM_UseLatched} 18834345a63Smrg , 18934345a63Smrg {"locked", XkbIM_UseLocked} 19034345a63Smrg , 19134345a63Smrg {"effective", XkbIM_UseEffective} 19234345a63Smrg , 19334345a63Smrg {"any", XkbIM_UseAnyGroup} 19434345a63Smrg , 19534345a63Smrg {"none", 0} 19634345a63Smrg , 19734345a63Smrg {NULL, 0} 198f46a6179Smrg}; 199f46a6179Smrg 200f46a6179Smrgint 20134345a63SmrgSetIndicatorMapField(LEDInfo * led, 20234345a63Smrg XkbDescPtr xkb, 203c82dfdfbSmrg const char *field, ExprDef *arrayNdx, 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 * 32634345a63SmrgHandleIndicatorMapDef(IndicatorMapDef * def, 32734345a63Smrg XkbDescPtr xkb, 32834345a63Smrg LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge) 329f46a6179Smrg{ 33034345a63Smrg LEDInfo led, *rtrn; 33134345a63Smrg VarDef *var; 33234345a63Smrg Bool ok; 333f46a6179Smrg 33434345a63Smrg if (def->merge != MergeDefault) 33534345a63Smrg merge = def->merge; 336f46a6179Smrg 33734345a63Smrg led = *dflt; 33834345a63Smrg led.defs.merge = merge; 33934345a63Smrg led.name = def->name; 34034345a63Smrg 34134345a63Smrg ok = True; 34234345a63Smrg for (var = def->body; var != NULL; var = (VarDef *) var->common.next) 34334345a63Smrg { 34434345a63Smrg ExprResult elem, field; 34534345a63Smrg ExprDef *arrayNdx; 34634345a63Smrg if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx)) 34734345a63Smrg { 34834345a63Smrg ok = False; 34934345a63Smrg continue; 35034345a63Smrg } 35134345a63Smrg if (elem.str != NULL) 35234345a63Smrg { 353bfe6082cSmrg ERROR 35434345a63Smrg ("Cannot set defaults for \"%s\" element in indicator map\n", 35534345a63Smrg elem.str); 356bfe6082cSmrg ACTION("Assignment to %s.%s ignored\n", elem.str, field.str); 35734345a63Smrg ok = False; 35834345a63Smrg } 35934345a63Smrg else 36034345a63Smrg { 36134345a63Smrg ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx, 36234345a63Smrg var->value) && ok; 36334345a63Smrg } 364f46a6179Smrg } 36534345a63Smrg if (ok) 36634345a63Smrg { 36734345a63Smrg rtrn = AddIndicatorMap(oldLEDs, &led); 36834345a63Smrg return rtrn; 369f46a6179Smrg } 370f46a6179Smrg return NULL; 371f46a6179Smrg} 372f46a6179Smrg 37334345a63SmrgBool 37434345a63SmrgCopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds, 37534345a63Smrg LEDInfo ** unboundRtrn) 376f46a6179Smrg{ 37734345a63Smrg LEDInfo *led, *next; 37834345a63Smrg LEDInfo *unbound, *last; 37934345a63Smrg XkbDescPtr xkb; 380f46a6179Smrg 38134345a63Smrg xkb = result->xkb; 38234345a63Smrg if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success) 38334345a63Smrg { 38434345a63Smrg WSGO("Couldn't allocate names\n"); 38534345a63Smrg ACTION("Indicator names may be incorrect\n"); 386f46a6179Smrg } 38734345a63Smrg if (XkbAllocIndicatorMaps(xkb) != Success) 38834345a63Smrg { 38934345a63Smrg WSGO("Can't allocate indicator maps\n"); 39034345a63Smrg ACTION("Indicator map definitions may be lost\n"); 39134345a63Smrg return False; 392f46a6179Smrg } 39334345a63Smrg last = unbound = (unboundRtrn ? *unboundRtrn : NULL); 39434345a63Smrg while ((last != NULL) && (last->defs.next != NULL)) 39534345a63Smrg { 39634345a63Smrg last = (LEDInfo *) last->defs.next; 397f46a6179Smrg } 39834345a63Smrg for (led = leds; led != NULL; led = next) 39934345a63Smrg { 40034345a63Smrg next = (LEDInfo *) led->defs.next; 40134345a63Smrg if ((led->groups != 0) && (led->which_groups == 0)) 40234345a63Smrg led->which_groups = XkbIM_UseEffective; 40334345a63Smrg if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods))) 40434345a63Smrg led->which_mods = XkbIM_UseEffective; 40534345a63Smrg if ((led->indicator == _LED_NotBound) || (!xkb->indicators)) 40634345a63Smrg { 40734345a63Smrg if (unboundRtrn != NULL) 40834345a63Smrg { 40934345a63Smrg led->defs.next = NULL; 41034345a63Smrg if (last != NULL) 41134345a63Smrg last->defs.next = (CommonInfo *) led; 41234345a63Smrg else 41334345a63Smrg unbound = led; 41434345a63Smrg last = led; 41534345a63Smrg } 41634345a63Smrg else 41734345a63Smrg uFree(led); 41834345a63Smrg } 41934345a63Smrg else 42034345a63Smrg { 42134345a63Smrg register XkbIndicatorMapPtr im; 42234345a63Smrg im = &xkb->indicators->maps[led->indicator - 1]; 42334345a63Smrg im->flags = led->flags; 42434345a63Smrg im->which_groups = led->which_groups; 42534345a63Smrg im->groups = led->groups; 42634345a63Smrg im->which_mods = led->which_mods; 42734345a63Smrg im->mods.mask = led->real_mods; 42834345a63Smrg im->mods.real_mods = led->real_mods; 42934345a63Smrg im->mods.vmods = led->vmods; 43034345a63Smrg im->ctrls = led->ctrls; 43134345a63Smrg if (xkb->names != NULL) 43234345a63Smrg xkb->names->indicators[led->indicator - 1] = led->name; 43334345a63Smrg uFree(led); 43434345a63Smrg } 435f46a6179Smrg } 43634345a63Smrg if (unboundRtrn != NULL) 43734345a63Smrg { 43834345a63Smrg *unboundRtrn = unbound; 439f46a6179Smrg } 440f46a6179Smrg return True; 441f46a6179Smrg} 442f46a6179Smrg 443f46a6179SmrgBool 44434345a63SmrgBindIndicators(XkbFileInfo * result, 44534345a63Smrg Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn) 446f46a6179Smrg{ 44734345a63Smrg XkbDescPtr xkb; 44834345a63Smrg register int i; 44934345a63Smrg register LEDInfo *led, *next, *last; 450f46a6179Smrg 45134345a63Smrg xkb = result->xkb; 45234345a63Smrg if (xkb->names != NULL) 45334345a63Smrg { 45434345a63Smrg for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) 45534345a63Smrg { 45634345a63Smrg if (led->indicator == _LED_NotBound) 45734345a63Smrg { 45834345a63Smrg for (i = 0; i < XkbNumIndicators; i++) 45934345a63Smrg { 46034345a63Smrg if (xkb->names->indicators[i] == led->name) 46134345a63Smrg { 46234345a63Smrg led->indicator = i + 1; 46334345a63Smrg break; 46434345a63Smrg } 46534345a63Smrg } 46634345a63Smrg } 46734345a63Smrg } 46834345a63Smrg if (force) 46934345a63Smrg { 47034345a63Smrg for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) 47134345a63Smrg { 47234345a63Smrg if (led->indicator == _LED_NotBound) 47334345a63Smrg { 47434345a63Smrg for (i = 0; i < XkbNumIndicators; i++) 47534345a63Smrg { 47634345a63Smrg if (xkb->names->indicators[i] == None) 47734345a63Smrg { 47834345a63Smrg xkb->names->indicators[i] = led->name; 47934345a63Smrg led->indicator = i + 1; 48034345a63Smrg xkb->indicators->phys_indicators &= ~(1 << i); 48134345a63Smrg break; 48234345a63Smrg } 48334345a63Smrg } 48434345a63Smrg if (led->indicator == _LED_NotBound) 48534345a63Smrg { 48634345a63Smrg ERROR("No unnamed indicators found\n"); 487bfe6082cSmrg ACTION 48834345a63Smrg ("Virtual indicator map \"%s\" not bound\n", 48934345a63Smrg XkbAtomGetString(xkb->dpy, led->name)); 49034345a63Smrg continue; 49134345a63Smrg } 49234345a63Smrg } 49334345a63Smrg } 49434345a63Smrg } 495f46a6179Smrg } 49634345a63Smrg for (last = NULL, led = unbound; led != NULL; led = next) 49734345a63Smrg { 49834345a63Smrg next = (LEDInfo *) led->defs.next; 49934345a63Smrg if (led->indicator == _LED_NotBound) 50034345a63Smrg { 50134345a63Smrg if (force) 50234345a63Smrg { 50334345a63Smrg unbound = next; 50434345a63Smrg uFree(led); 50534345a63Smrg } 50634345a63Smrg else 50734345a63Smrg { 50834345a63Smrg if (last) 50934345a63Smrg last->defs.next = &led->defs; 51034345a63Smrg else 51134345a63Smrg unbound = led; 51234345a63Smrg last = led; 51334345a63Smrg } 51434345a63Smrg } 51534345a63Smrg else 51634345a63Smrg { 51734345a63Smrg if ((xkb->names != NULL) && 51834345a63Smrg (xkb->names->indicators[led->indicator - 1] != led->name)) 51934345a63Smrg { 52034345a63Smrg Atom old = xkb->names->indicators[led->indicator - 1]; 521bfe6082cSmrg ERROR("Multiple names bound to indicator %d\n", 52234345a63Smrg (unsigned int) led->indicator); 523bfe6082cSmrg ACTION("Using %s, ignoring %s\n", 52434345a63Smrg XkbAtomGetString(xkb->dpy, old), 52534345a63Smrg XkbAtomGetString(xkb->dpy, led->name)); 52634345a63Smrg led->indicator = _LED_NotBound; 52734345a63Smrg if (force) 52834345a63Smrg { 52934345a63Smrg uFree(led); 53034345a63Smrg unbound = next; 53134345a63Smrg } 53234345a63Smrg else 53334345a63Smrg { 53434345a63Smrg if (last) 53534345a63Smrg last->defs.next = &led->defs; 53634345a63Smrg else 53734345a63Smrg unbound = led; 53834345a63Smrg last = led; 53934345a63Smrg } 54034345a63Smrg } 54134345a63Smrg else 54234345a63Smrg { 54334345a63Smrg XkbIndicatorMapPtr map; 54434345a63Smrg map = &xkb->indicators->maps[led->indicator - 1]; 54534345a63Smrg map->flags = led->flags; 54634345a63Smrg map->which_groups = led->which_groups; 54734345a63Smrg map->groups = led->groups; 54834345a63Smrg map->which_mods = led->which_mods; 54934345a63Smrg map->mods.mask = led->real_mods; 55034345a63Smrg map->mods.real_mods = led->real_mods; 55134345a63Smrg map->mods.vmods = led->vmods; 55234345a63Smrg map->ctrls = led->ctrls; 55334345a63Smrg if (last) 55434345a63Smrg last->defs.next = &next->defs; 55534345a63Smrg else 55634345a63Smrg unbound = next; 55734345a63Smrg led->defs.next = NULL; 55834345a63Smrg uFree(led); 55934345a63Smrg } 56034345a63Smrg } 561f46a6179Smrg } 56234345a63Smrg if (unboundRtrn) 56334345a63Smrg { 56434345a63Smrg *unboundRtrn = unbound; 565f46a6179Smrg } 56634345a63Smrg else if (unbound) 56734345a63Smrg { 56834345a63Smrg for (led = unbound; led != NULL; led = next) 56934345a63Smrg { 57034345a63Smrg next = (LEDInfo *) led->defs.next; 57134345a63Smrg uFree(led); 57234345a63Smrg } 573f46a6179Smrg } 574f46a6179Smrg return True; 575f46a6179Smrg} 576