diff options
Diffstat (limited to 'xkbcomp/indicators.c')
-rw-r--r-- | xkbcomp/indicators.c | 1150 |
1 files changed, 575 insertions, 575 deletions
diff --git a/xkbcomp/indicators.c b/xkbcomp/indicators.c index d4a362fb8..63dc18b7b 100644 --- a/xkbcomp/indicators.c +++ b/xkbcomp/indicators.c @@ -1,575 +1,575 @@ -/************************************************************ - Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - - Permission to use, copy, modify, and distribute this - software and its documentation for any purpose and without - fee is hereby granted, provided that the above copyright - notice appear in all copies and that both that copyright - notice and this permission notice appear in supporting - documentation, and that the name of Silicon Graphics not be - used in advertising or publicity pertaining to distribution - of the software without specific prior written permission. - Silicon Graphics makes no representation about the suitability - of this software for any purpose. It is provided "as is" - without any express or implied warranty. - - SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ********************************************************/ - -#include "xkbcomp.h" -#include "misc.h" -#include "tokens.h" -#include "expr.h" -#include "vmod.h" -#include "indicators.h" -#include "action.h" -#include "compat.h" - -/***====================================================================***/ - -#define ReportIndicatorBadType(d,l,f,w) \ - ReportBadType("indicator map",(f),\ - XkbAtomText((d),(l)->name,XkbMessage),(w)) -#define ReportIndicatorNotArray(d,l,f) \ - ReportNotArray("indicator map",(f),\ - XkbAtomText((d),(l)->name,XkbMessage)) - -/***====================================================================***/ - -void -ClearIndicatorMapInfo(Display * dpy, LEDInfo * info) -{ - info->name = XkbInternAtom(dpy, "default", False); - info->indicator = _LED_NotBound; - info->flags = info->which_mods = info->real_mods = 0; - info->vmods = 0; - info->which_groups = info->groups = 0; - info->ctrls = 0; - return; -} - -LEDInfo * -AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new) -{ - LEDInfo *old, *last; - unsigned collide; - - last = NULL; - for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next) - { - if (old->name == new->name) - { - if ((old->real_mods == new->real_mods) && - (old->vmods == new->vmods) && - (old->groups == new->groups) && - (old->ctrls == new->ctrls) && - (old->which_mods == new->which_mods) && - (old->which_groups == new->which_groups)) - { - old->defs.defined |= new->defs.defined; - return oldLEDs; - } - if (new->defs.merge == MergeReplace) - { - CommonInfo *next = old->defs.next; - if (((old->defs.fileID == new->defs.fileID) - && (warningLevel > 0)) || (warningLevel > 9)) - { - WARN1("Map for indicator %s redefined\n", - XkbAtomText(NULL, old->name, XkbMessage)); - ACTION("Earlier definition ignored\n"); - } - *old = *new; - old->defs.next = next; - return oldLEDs; - } - collide = 0; - if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide)) - { - old->indicator = new->indicator; - old->defs.defined |= _LED_Index; - } - if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide)) - { - old->which_mods = new->which_mods; - old->real_mods = new->real_mods; - old->vmods = new->vmods; - old->defs.defined |= _LED_Mods; - } - if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide)) - { - old->which_groups = new->which_groups; - old->groups = new->groups; - old->defs.defined |= _LED_Groups; - } - if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide)) - { - old->ctrls = new->ctrls; - old->defs.defined |= _LED_Ctrls; - } - if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide)) - { - old->flags &= ~XkbIM_NoExplicit; - old->flags |= (new->flags & XkbIM_NoExplicit); - old->defs.defined |= _LED_Explicit; - } - if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide)) - { - old->flags &= ~XkbIM_NoAutomatic; - old->flags |= (new->flags & XkbIM_NoAutomatic); - old->defs.defined |= _LED_Automatic; - } - if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide)) - { - old->flags &= ~XkbIM_LEDDrivesKB; - old->flags |= (new->flags & XkbIM_LEDDrivesKB); - old->defs.defined |= _LED_DrivesKbd; - } - if (collide) - { - WARN1("Map for indicator %s redefined\n", - XkbAtomText(NULL, old->name, XkbMessage)); - ACTION1("Using %s definition for duplicate fields\n", - (new->defs.merge == MergeAugment ? "first" : "last")); - } - return oldLEDs; - } - if (old->defs.next == NULL) - last = old; - } - /* new definition */ - old = uTypedAlloc(LEDInfo); - if (!old) - { - WSGO("Couldn't allocate indicator map\n"); - ACTION1("Map for indicator %s not compiled\n", - XkbAtomText(NULL, new->name, XkbMessage)); - return NULL; - } - *old = *new; - old->defs.next = NULL; - if (last) - { - last->defs.next = &old->defs; - return oldLEDs; - } - return old; -} - -static LookupEntry modComponentNames[] = { - {"base", XkbIM_UseBase} - , - {"latched", XkbIM_UseLatched} - , - {"locked", XkbIM_UseLocked} - , - {"effective", XkbIM_UseEffective} - , - {"compat", XkbIM_UseCompat} - , - {"any", XkbIM_UseAnyMods} - , - {"none", 0} - , - {NULL, 0} -}; -static LookupEntry groupComponentNames[] = { - {"base", XkbIM_UseBase} - , - {"latched", XkbIM_UseLatched} - , - {"locked", XkbIM_UseLocked} - , - {"effective", XkbIM_UseEffective} - , - {"any", XkbIM_UseAnyGroup} - , - {"none", 0} - , - {NULL, 0} -}; - -int -SetIndicatorMapField(LEDInfo * led, - XkbDescPtr xkb, - char *field, ExprDef * arrayNdx, ExprDef * value) -{ - ExprResult rtrn; - Bool ok; - - ok = True; - if ((uStrCaseCmp(field, "modifiers") == 0) - || (uStrCaseCmp(field, "mods") == 0)) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb)) - return ReportIndicatorBadType(xkb->dpy, led, field, - "modifier mask"); - led->real_mods = rtrn.uval & 0xff; - led->vmods = (rtrn.uval >> 8) & 0xff; - led->defs.defined |= _LED_Mods; - } - else if (uStrCaseCmp(field, "groups") == 0) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveMask - (value, &rtrn, SimpleLookup, (XPointer) groupNames)) - return ReportIndicatorBadType(xkb->dpy, led, field, "group mask"); - led->groups = rtrn.uval; - led->defs.defined |= _LED_Groups; - } - else if ((uStrCaseCmp(field, "controls") == 0) || - (uStrCaseCmp(field, "ctrls") == 0)) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveMask - (value, &rtrn, SimpleLookup, (XPointer) ctrlNames)) - return ReportIndicatorBadType(xkb->dpy, led, field, - "controls mask"); - led->ctrls = rtrn.uval; - led->defs.defined |= _LED_Ctrls; - } - else if (uStrCaseCmp(field, "allowexplicit") == 0) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) - return ReportIndicatorBadType(xkb->dpy, led, field, "boolean"); - if (rtrn.uval) - led->flags &= ~XkbIM_NoExplicit; - else - led->flags |= XkbIM_NoExplicit; - led->defs.defined |= _LED_Explicit; - } - else if ((uStrCaseCmp(field, "whichmodstate") == 0) || - (uStrCaseCmp(field, "whichmodifierstate") == 0)) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveMask(value, &rtrn, SimpleLookup, - (XPointer) modComponentNames)) - { - return ReportIndicatorBadType(xkb->dpy, led, field, - "mask of modifier state components"); - } - led->which_mods = rtrn.uval; - } - else if (uStrCaseCmp(field, "whichgroupstate") == 0) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveMask(value, &rtrn, SimpleLookup, - (XPointer) groupComponentNames)) - { - return ReportIndicatorBadType(xkb->dpy, led, field, - "mask of group state components"); - } - led->which_groups = rtrn.uval; - } - else if ((uStrCaseCmp(field, "driveskbd") == 0) || - (uStrCaseCmp(field, "driveskeyboard") == 0) || - (uStrCaseCmp(field, "leddriveskbd") == 0) || - (uStrCaseCmp(field, "leddriveskeyboard") == 0) || - (uStrCaseCmp(field, "indicatordriveskbd") == 0) || - (uStrCaseCmp(field, "indicatordriveskeyboard") == 0)) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveBoolean(value, &rtrn, NULL, NULL)) - return ReportIndicatorBadType(xkb->dpy, led, field, "boolean"); - if (rtrn.uval) - led->flags |= XkbIM_LEDDrivesKB; - else - led->flags &= ~XkbIM_LEDDrivesKB; - led->defs.defined |= _LED_DrivesKbd; - } - else if (uStrCaseCmp(field, "index") == 0) - { - if (arrayNdx != NULL) - return ReportIndicatorNotArray(xkb->dpy, led, field); - if (!ExprResolveInteger(value, &rtrn, NULL, NULL)) - return ReportIndicatorBadType(xkb->dpy, led, field, - "indicator index"); - if ((rtrn.uval < 1) || (rtrn.uval > 32)) - { - ERROR2("Illegal indicator index %d (range 1..%d)\n", - rtrn.uval, XkbNumIndicators); - ACTION1("Index definition for %s indicator ignored\n", - XkbAtomText(NULL, led->name, XkbMessage)); - return False; - } - led->indicator = rtrn.uval; - led->defs.defined |= _LED_Index; - } - else - { - ERROR2("Unknown field %s in map for %s indicator\n", field, - XkbAtomText(NULL, led->name, XkbMessage)); - ACTION("Definition ignored\n"); - ok = False; - } - return ok; -} - -LEDInfo * -HandleIndicatorMapDef(IndicatorMapDef * def, - XkbDescPtr xkb, - LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge) -{ - LEDInfo led, *rtrn; - VarDef *var; - Bool ok; - - if (def->merge != MergeDefault) - merge = def->merge; - - led = *dflt; - led.defs.merge = merge; - led.name = def->name; - - ok = True; - for (var = def->body; var != NULL; var = (VarDef *) var->common.next) - { - ExprResult elem, field; - ExprDef *arrayNdx; - if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx)) - { - ok = False; - continue; - } - if (elem.str != NULL) - { - ERROR1 - ("Cannot set defaults for \"%s\" element in indicator map\n", - elem.str); - ACTION2("Assignment to %s.%s ignored\n", elem.str, field.str); - ok = False; - } - else - { - ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx, - var->value) && ok; - } - } - if (ok) - { - rtrn = AddIndicatorMap(oldLEDs, &led); - return rtrn; - } - return NULL; -} - -Bool -CopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds, - LEDInfo ** unboundRtrn) -{ - LEDInfo *led, *next; - LEDInfo *unbound, *last; - XkbDescPtr xkb; - - xkb = result->xkb; - if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success) - { - WSGO("Couldn't allocate names\n"); - ACTION("Indicator names may be incorrect\n"); - } - if (XkbAllocIndicatorMaps(xkb) != Success) - { - WSGO("Can't allocate indicator maps\n"); - ACTION("Indicator map definitions may be lost\n"); - return False; - } - last = unbound = (unboundRtrn ? *unboundRtrn : NULL); - while ((last != NULL) && (last->defs.next != NULL)) - { - last = (LEDInfo *) last->defs.next; - } - for (led = leds; led != NULL; led = next) - { - next = (LEDInfo *) led->defs.next; - if ((led->groups != 0) && (led->which_groups == 0)) - led->which_groups = XkbIM_UseEffective; - if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods))) - led->which_mods = XkbIM_UseEffective; - if ((led->indicator == _LED_NotBound) || (!xkb->indicators)) - { - if (unboundRtrn != NULL) - { - led->defs.next = NULL; - if (last != NULL) - last->defs.next = (CommonInfo *) led; - else - unbound = led; - last = led; - } - else - uFree(led); - } - else - { - register XkbIndicatorMapPtr im; - im = &xkb->indicators->maps[led->indicator - 1]; - im->flags = led->flags; - im->which_groups = led->which_groups; - im->groups = led->groups; - im->which_mods = led->which_mods; - im->mods.mask = led->real_mods; - im->mods.real_mods = led->real_mods; - im->mods.vmods = led->vmods; - im->ctrls = led->ctrls; - if (xkb->names != NULL) - xkb->names->indicators[led->indicator - 1] = led->name; - uFree(led); - } - } - if (unboundRtrn != NULL) - { - *unboundRtrn = unbound; - } - return True; -} - -Bool -BindIndicators(XkbFileInfo * result, - Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn) -{ - XkbDescPtr xkb; - register int i; - register LEDInfo *led, *next, *last; - - xkb = result->xkb; - if (xkb->names != NULL) - { - for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) - { - if (led->indicator == _LED_NotBound) - { - for (i = 0; i < XkbNumIndicators; i++) - { - if (xkb->names->indicators[i] == led->name) - { - led->indicator = i + 1; - break; - } - } - } - } - if (force) - { - for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next) - { - if (led->indicator == _LED_NotBound) - { - for (i = 0; i < XkbNumIndicators; i++) - { - if (xkb->names->indicators[i] == None) - { - xkb->names->indicators[i] = led->name; - led->indicator = i + 1; - xkb->indicators->phys_indicators &= ~(1 << i); - break; - } - } - if (led->indicator == _LED_NotBound) - { - ERROR("No unnamed indicators found\n"); - ACTION1 - ("Virtual indicator map \"%s\" not bound\n", - XkbAtomGetString(xkb->dpy, led->name)); - continue; - } - } - } - } - } - for (last = NULL, led = unbound; led != NULL; led = next) - { - next = (LEDInfo *) led->defs.next; - if (led->indicator == _LED_NotBound) - { - if (force) - { - unbound = next; - uFree(led); - } - else - { - if (last) - last->defs.next = &led->defs; - else - unbound = led; - last = led; - } - } - else - { - if ((xkb->names != NULL) && - (xkb->names->indicators[led->indicator - 1] != led->name)) - { - Atom old = xkb->names->indicators[led->indicator - 1]; - ERROR1("Multiple names bound to indicator %d\n", - (unsigned int) led->indicator); - ACTION2("Using %s, ignoring %s\n", - XkbAtomGetString(xkb->dpy, old), - XkbAtomGetString(xkb->dpy, led->name)); - led->indicator = _LED_NotBound; - if (force) - { - uFree(led); - unbound = next; - } - else - { - if (last) - last->defs.next = &led->defs; - else - unbound = led; - last = led; - } - } - else - { - XkbIndicatorMapPtr map; - map = &xkb->indicators->maps[led->indicator - 1]; - map->flags = led->flags; - map->which_groups = led->which_groups; - map->groups = led->groups; - map->which_mods = led->which_mods; - map->mods.mask = led->real_mods; - map->mods.real_mods = led->real_mods; - map->mods.vmods = led->vmods; - map->ctrls = led->ctrls; - if (last) - last->defs.next = &next->defs; - else - unbound = next; - led->defs.next = NULL; - uFree(led); - } - } - } - if (unboundRtrn) - { - *unboundRtrn = unbound; - } - else if (unbound) - { - for (led = unbound; led != NULL; led = next) - { - next = (LEDInfo *) led->defs.next; - uFree(led); - } - } - return True; -} +/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#include "xkbcomp.h"
+#include "misc.h"
+#include "tokens.h"
+#include "expr.h"
+#include "vmod.h"
+#include "indicators.h"
+#include "action.h"
+#include "compat.h"
+
+/***====================================================================***/
+
+#define ReportIndicatorBadType(d,l,f,w) \
+ ReportBadType("indicator map",(f),\
+ XkbAtomText((d),(l)->name,XkbMessage),(w))
+#define ReportIndicatorNotArray(d,l,f) \
+ ReportNotArray("indicator map",(f),\
+ XkbAtomText((d),(l)->name,XkbMessage))
+
+/***====================================================================***/
+
+void
+ClearIndicatorMapInfo(Display * dpy, LEDInfo * info)
+{
+ info->name = XkbInternAtom(dpy, "default", False);
+ info->indicator = _LED_NotBound;
+ info->flags = info->which_mods = info->real_mods = 0;
+ info->vmods = 0;
+ info->which_groups = info->groups = 0;
+ info->ctrls = 0;
+ return;
+}
+
+LEDInfo *
+AddIndicatorMap(LEDInfo * oldLEDs, LEDInfo * new)
+{
+ LEDInfo *old, *last;
+ unsigned collide;
+
+ last = NULL;
+ for (old = oldLEDs; old != NULL; old = (LEDInfo *) old->defs.next)
+ {
+ if (old->name == new->name)
+ {
+ if ((old->real_mods == new->real_mods) &&
+ (old->vmods == new->vmods) &&
+ (old->groups == new->groups) &&
+ (old->ctrls == new->ctrls) &&
+ (old->which_mods == new->which_mods) &&
+ (old->which_groups == new->which_groups))
+ {
+ old->defs.defined |= new->defs.defined;
+ return oldLEDs;
+ }
+ if (new->defs.merge == MergeReplace)
+ {
+ CommonInfo *next = old->defs.next;
+ if (((old->defs.fileID == new->defs.fileID)
+ && (warningLevel > 0)) || (warningLevel > 9))
+ {
+ WARN1("Map for indicator %s redefined\n",
+ XkbAtomText(NULL, old->name, XkbMessage));
+ ACTION("Earlier definition ignored\n");
+ }
+ *old = *new;
+ old->defs.next = next;
+ return oldLEDs;
+ }
+ collide = 0;
+ if (UseNewField(_LED_Index, &old->defs, &new->defs, &collide))
+ {
+ old->indicator = new->indicator;
+ old->defs.defined |= _LED_Index;
+ }
+ if (UseNewField(_LED_Mods, &old->defs, &new->defs, &collide))
+ {
+ old->which_mods = new->which_mods;
+ old->real_mods = new->real_mods;
+ old->vmods = new->vmods;
+ old->defs.defined |= _LED_Mods;
+ }
+ if (UseNewField(_LED_Groups, &old->defs, &new->defs, &collide))
+ {
+ old->which_groups = new->which_groups;
+ old->groups = new->groups;
+ old->defs.defined |= _LED_Groups;
+ }
+ if (UseNewField(_LED_Ctrls, &old->defs, &new->defs, &collide))
+ {
+ old->ctrls = new->ctrls;
+ old->defs.defined |= _LED_Ctrls;
+ }
+ if (UseNewField(_LED_Explicit, &old->defs, &new->defs, &collide))
+ {
+ old->flags &= ~XkbIM_NoExplicit;
+ old->flags |= (new->flags & XkbIM_NoExplicit);
+ old->defs.defined |= _LED_Explicit;
+ }
+ if (UseNewField(_LED_Automatic, &old->defs, &new->defs, &collide))
+ {
+ old->flags &= ~XkbIM_NoAutomatic;
+ old->flags |= (new->flags & XkbIM_NoAutomatic);
+ old->defs.defined |= _LED_Automatic;
+ }
+ if (UseNewField(_LED_DrivesKbd, &old->defs, &new->defs, &collide))
+ {
+ old->flags &= ~XkbIM_LEDDrivesKB;
+ old->flags |= (new->flags & XkbIM_LEDDrivesKB);
+ old->defs.defined |= _LED_DrivesKbd;
+ }
+ if (collide)
+ {
+ WARN1("Map for indicator %s redefined\n",
+ XkbAtomText(NULL, old->name, XkbMessage));
+ ACTION1("Using %s definition for duplicate fields\n",
+ (new->defs.merge == MergeAugment ? "first" : "last"));
+ }
+ return oldLEDs;
+ }
+ if (old->defs.next == NULL)
+ last = old;
+ }
+ /* new definition */
+ old = uTypedAlloc(LEDInfo);
+ if (!old)
+ {
+ WSGO("Couldn't allocate indicator map\n");
+ ACTION1("Map for indicator %s not compiled\n",
+ XkbAtomText(NULL, new->name, XkbMessage));
+ return NULL;
+ }
+ *old = *new;
+ old->defs.next = NULL;
+ if (last)
+ {
+ last->defs.next = &old->defs;
+ return oldLEDs;
+ }
+ return old;
+}
+
+static LookupEntry modComponentNames[] = {
+ {"base", XkbIM_UseBase}
+ ,
+ {"latched", XkbIM_UseLatched}
+ ,
+ {"locked", XkbIM_UseLocked}
+ ,
+ {"effective", XkbIM_UseEffective}
+ ,
+ {"compat", XkbIM_UseCompat}
+ ,
+ {"any", XkbIM_UseAnyMods}
+ ,
+ {"none", 0}
+ ,
+ {NULL, 0}
+};
+static LookupEntry groupComponentNames[] = {
+ {"base", XkbIM_UseBase}
+ ,
+ {"latched", XkbIM_UseLatched}
+ ,
+ {"locked", XkbIM_UseLocked}
+ ,
+ {"effective", XkbIM_UseEffective}
+ ,
+ {"any", XkbIM_UseAnyGroup}
+ ,
+ {"none", 0}
+ ,
+ {NULL, 0}
+};
+
+int
+SetIndicatorMapField(LEDInfo * led,
+ XkbDescPtr xkb,
+ char *field, ExprDef * arrayNdx, ExprDef * value)
+{
+ ExprResult rtrn;
+ Bool ok;
+
+ ok = True;
+ if ((uStrCaseCmp(field, "modifiers") == 0)
+ || (uStrCaseCmp(field, "mods") == 0))
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveModMask(value, &rtrn, LookupVModMask, (XPointer) xkb))
+ return ReportIndicatorBadType(xkb->dpy, led, field,
+ "modifier mask");
+ led->real_mods = rtrn.uval & 0xff;
+ led->vmods = (rtrn.uval >> 8) & 0xff;
+ led->defs.defined |= _LED_Mods;
+ }
+ else if (uStrCaseCmp(field, "groups") == 0)
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveMask
+ (value, &rtrn, SimpleLookup, (XPointer) groupNames))
+ return ReportIndicatorBadType(xkb->dpy, led, field, "group mask");
+ led->groups = rtrn.uval;
+ led->defs.defined |= _LED_Groups;
+ }
+ else if ((uStrCaseCmp(field, "controls") == 0) ||
+ (uStrCaseCmp(field, "ctrls") == 0))
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveMask
+ (value, &rtrn, SimpleLookup, (XPointer) ctrlNames))
+ return ReportIndicatorBadType(xkb->dpy, led, field,
+ "controls mask");
+ led->ctrls = rtrn.uval;
+ led->defs.defined |= _LED_Ctrls;
+ }
+ else if (uStrCaseCmp(field, "allowexplicit") == 0)
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
+ return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
+ if (rtrn.uval)
+ led->flags &= ~XkbIM_NoExplicit;
+ else
+ led->flags |= XkbIM_NoExplicit;
+ led->defs.defined |= _LED_Explicit;
+ }
+ else if ((uStrCaseCmp(field, "whichmodstate") == 0) ||
+ (uStrCaseCmp(field, "whichmodifierstate") == 0))
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveMask(value, &rtrn, SimpleLookup,
+ (XPointer) modComponentNames))
+ {
+ return ReportIndicatorBadType(xkb->dpy, led, field,
+ "mask of modifier state components");
+ }
+ led->which_mods = rtrn.uval;
+ }
+ else if (uStrCaseCmp(field, "whichgroupstate") == 0)
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveMask(value, &rtrn, SimpleLookup,
+ (XPointer) groupComponentNames))
+ {
+ return ReportIndicatorBadType(xkb->dpy, led, field,
+ "mask of group state components");
+ }
+ led->which_groups = rtrn.uval;
+ }
+ else if ((uStrCaseCmp(field, "driveskbd") == 0) ||
+ (uStrCaseCmp(field, "driveskeyboard") == 0) ||
+ (uStrCaseCmp(field, "leddriveskbd") == 0) ||
+ (uStrCaseCmp(field, "leddriveskeyboard") == 0) ||
+ (uStrCaseCmp(field, "indicatordriveskbd") == 0) ||
+ (uStrCaseCmp(field, "indicatordriveskeyboard") == 0))
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveBoolean(value, &rtrn, NULL, NULL))
+ return ReportIndicatorBadType(xkb->dpy, led, field, "boolean");
+ if (rtrn.uval)
+ led->flags |= XkbIM_LEDDrivesKB;
+ else
+ led->flags &= ~XkbIM_LEDDrivesKB;
+ led->defs.defined |= _LED_DrivesKbd;
+ }
+ else if (uStrCaseCmp(field, "index") == 0)
+ {
+ if (arrayNdx != NULL)
+ return ReportIndicatorNotArray(xkb->dpy, led, field);
+ if (!ExprResolveInteger(value, &rtrn, NULL, NULL))
+ return ReportIndicatorBadType(xkb->dpy, led, field,
+ "indicator index");
+ if ((rtrn.uval < 1) || (rtrn.uval > 32))
+ {
+ ERROR2("Illegal indicator index %d (range 1..%d)\n",
+ rtrn.uval, XkbNumIndicators);
+ ACTION1("Index definition for %s indicator ignored\n",
+ XkbAtomText(NULL, led->name, XkbMessage));
+ return False;
+ }
+ led->indicator = rtrn.uval;
+ led->defs.defined |= _LED_Index;
+ }
+ else
+ {
+ ERROR2("Unknown field %s in map for %s indicator\n", field,
+ XkbAtomText(NULL, led->name, XkbMessage));
+ ACTION("Definition ignored\n");
+ ok = False;
+ }
+ return ok;
+}
+
+LEDInfo *
+HandleIndicatorMapDef(IndicatorMapDef * def,
+ XkbDescPtr xkb,
+ LEDInfo * dflt, LEDInfo * oldLEDs, unsigned merge)
+{
+ LEDInfo led, *rtrn;
+ VarDef *var;
+ Bool ok;
+
+ if (def->merge != MergeDefault)
+ merge = def->merge;
+
+ led = *dflt;
+ led.defs.merge = merge;
+ led.name = def->name;
+
+ ok = True;
+ for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
+ {
+ ExprResult elem, field;
+ ExprDef *arrayNdx;
+ if (!ExprResolveLhs(var->name, &elem, &field, &arrayNdx))
+ {
+ ok = False;
+ continue;
+ }
+ if (elem.str != NULL)
+ {
+ ERROR1
+ ("Cannot set defaults for \"%s\" element in indicator map\n",
+ elem.str);
+ ACTION2("Assignment to %s.%s ignored\n", elem.str, field.str);
+ ok = False;
+ }
+ else
+ {
+ ok = SetIndicatorMapField(&led, xkb, field.str, arrayNdx,
+ var->value) && ok;
+ }
+ }
+ if (ok)
+ {
+ rtrn = AddIndicatorMap(oldLEDs, &led);
+ return rtrn;
+ }
+ return NULL;
+}
+
+Bool
+CopyIndicatorMapDefs(XkbFileInfo * result, LEDInfo * leds,
+ LEDInfo ** unboundRtrn)
+{
+ LEDInfo *led, *next;
+ LEDInfo *unbound, *last;
+ XkbDescPtr xkb;
+
+ xkb = result->xkb;
+ if (XkbAllocNames(xkb, XkbIndicatorNamesMask, 0, 0) != Success)
+ {
+ WSGO("Couldn't allocate names\n");
+ ACTION("Indicator names may be incorrect\n");
+ }
+ if (XkbAllocIndicatorMaps(xkb) != Success)
+ {
+ WSGO("Can't allocate indicator maps\n");
+ ACTION("Indicator map definitions may be lost\n");
+ return False;
+ }
+ last = unbound = (unboundRtrn ? *unboundRtrn : NULL);
+ while ((last != NULL) && (last->defs.next != NULL))
+ {
+ last = (LEDInfo *) last->defs.next;
+ }
+ for (led = leds; led != NULL; led = next)
+ {
+ next = (LEDInfo *) led->defs.next;
+ if ((led->groups != 0) && (led->which_groups == 0))
+ led->which_groups = XkbIM_UseEffective;
+ if ((led->which_mods == 0) && ((led->real_mods) || (led->vmods)))
+ led->which_mods = XkbIM_UseEffective;
+ if ((led->indicator == _LED_NotBound) || (!xkb->indicators))
+ {
+ if (unboundRtrn != NULL)
+ {
+ led->defs.next = NULL;
+ if (last != NULL)
+ last->defs.next = (CommonInfo *) led;
+ else
+ unbound = led;
+ last = led;
+ }
+ else
+ uFree(led);
+ }
+ else
+ {
+ register XkbIndicatorMapPtr im;
+ im = &xkb->indicators->maps[led->indicator - 1];
+ im->flags = led->flags;
+ im->which_groups = led->which_groups;
+ im->groups = led->groups;
+ im->which_mods = led->which_mods;
+ im->mods.mask = led->real_mods;
+ im->mods.real_mods = led->real_mods;
+ im->mods.vmods = led->vmods;
+ im->ctrls = led->ctrls;
+ if (xkb->names != NULL)
+ xkb->names->indicators[led->indicator - 1] = led->name;
+ uFree(led);
+ }
+ }
+ if (unboundRtrn != NULL)
+ {
+ *unboundRtrn = unbound;
+ }
+ return True;
+}
+
+Bool
+BindIndicators(XkbFileInfo * result,
+ Bool force, LEDInfo * unbound, LEDInfo ** unboundRtrn)
+{
+ XkbDescPtr xkb;
+ register int i;
+ register LEDInfo *led, *next, *last;
+
+ xkb = result->xkb;
+ if (xkb->names != NULL)
+ {
+ for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
+ {
+ if (led->indicator == _LED_NotBound)
+ {
+ for (i = 0; i < XkbNumIndicators; i++)
+ {
+ if (xkb->names->indicators[i] == led->name)
+ {
+ led->indicator = i + 1;
+ break;
+ }
+ }
+ }
+ }
+ if (force)
+ {
+ for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
+ {
+ if (led->indicator == _LED_NotBound)
+ {
+ for (i = 0; i < XkbNumIndicators; i++)
+ {
+ if (xkb->names->indicators[i] == None)
+ {
+ xkb->names->indicators[i] = led->name;
+ led->indicator = i + 1;
+ xkb->indicators->phys_indicators &= ~(1 << i);
+ break;
+ }
+ }
+ if (led->indicator == _LED_NotBound)
+ {
+ ERROR("No unnamed indicators found\n");
+ ACTION1
+ ("Virtual indicator map \"%s\" not bound\n",
+ XkbAtomGetString(xkb->dpy, led->name));
+ continue;
+ }
+ }
+ }
+ }
+ }
+ for (last = NULL, led = unbound; led != NULL; led = next)
+ {
+ next = (LEDInfo *) led->defs.next;
+ if (led->indicator == _LED_NotBound)
+ {
+ if (force)
+ {
+ unbound = next;
+ uFree(led);
+ }
+ else
+ {
+ if (last)
+ last->defs.next = &led->defs;
+ else
+ unbound = led;
+ last = led;
+ }
+ }
+ else
+ {
+ if ((xkb->names != NULL) &&
+ (xkb->names->indicators[led->indicator - 1] != led->name))
+ {
+ Atom old = xkb->names->indicators[led->indicator - 1];
+ ERROR1("Multiple names bound to indicator %d\n",
+ (unsigned int) led->indicator);
+ ACTION2("Using %s, ignoring %s\n",
+ XkbAtomGetString(xkb->dpy, old),
+ XkbAtomGetString(xkb->dpy, led->name));
+ led->indicator = _LED_NotBound;
+ if (force)
+ {
+ uFree(led);
+ unbound = next;
+ }
+ else
+ {
+ if (last)
+ last->defs.next = &led->defs;
+ else
+ unbound = led;
+ last = led;
+ }
+ }
+ else
+ {
+ XkbIndicatorMapPtr map;
+ map = &xkb->indicators->maps[led->indicator - 1];
+ map->flags = led->flags;
+ map->which_groups = led->which_groups;
+ map->groups = led->groups;
+ map->which_mods = led->which_mods;
+ map->mods.mask = led->real_mods;
+ map->mods.real_mods = led->real_mods;
+ map->mods.vmods = led->vmods;
+ map->ctrls = led->ctrls;
+ if (last)
+ last->defs.next = &next->defs;
+ else
+ unbound = next;
+ led->defs.next = NULL;
+ uFree(led);
+ }
+ }
+ }
+ if (unboundRtrn)
+ {
+ *unboundRtrn = unbound;
+ }
+ else if (unbound)
+ {
+ for (led = unbound; led != NULL; led = next)
+ {
+ next = (LEDInfo *) led->defs.next;
+ uFree(led);
+ }
+ }
+ return True;
+}
|