2009-03-27 07:55:32 -06:00
|
|
|
/************************************************************
|
|
|
|
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
|
2009-04-04 10:19:51 -06:00
|
|
|
documentation, and that the name of Silicon Graphics not be
|
|
|
|
used in advertising or publicity pertaining to distribution
|
2009-03-27 07:55:32 -06:00
|
|
|
of the software without specific prior written permission.
|
2009-04-04 10:19:51 -06:00
|
|
|
Silicon Graphics makes no representation about the suitability
|
2009-03-27 07:55:32 -06:00
|
|
|
of this software for any purpose. It is provided "as is"
|
|
|
|
without any express or implied warranty.
|
2009-04-04 10:19:51 -06:00
|
|
|
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
2009-03-27 07:55:32 -06:00
|
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
2009-04-04 10:19:51 -06:00
|
|
|
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
|
2009-03-27 07:55:32 -06:00
|
|
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
|
|
********************************************************/
|
|
|
|
|
|
|
|
#include "indicators.h"
|
2012-05-08 04:57:07 -06:00
|
|
|
#include "expr.h"
|
2009-03-27 07:55:32 -06:00
|
|
|
#include "action.h"
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
2012-05-09 04:50:05 -06:00
|
|
|
#define ReportIndicatorBadType(keymap, l, f, w) \
|
|
|
|
ReportBadType("indicator map", (f), \
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text((keymap)->ctx, (l)->name), (w))
|
2012-05-09 04:50:05 -06:00
|
|
|
#define ReportIndicatorNotArray(keymap, l, f) \
|
|
|
|
ReportNotArray("indicator map", (f), \
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text((keymap)->ctx, (l)->name))
|
2009-03-27 07:55:32 -06:00
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
void
|
2012-05-11 08:03:43 -06:00
|
|
|
ClearIndicatorMapInfo(struct xkb_context *ctx, LEDInfo * info)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-05-09 06:03:11 -06:00
|
|
|
info->name = xkb_atom_intern(ctx, "default");
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
LEDInfo *
|
2012-05-09 04:50:05 -06:00
|
|
|
AddIndicatorMap(struct xkb_keymap *keymap, LEDInfo *oldLEDs, LEDInfo *new)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
WARN("Map for indicator %s redefined\n",
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, old->name));
|
2009-03-27 07:55:32 -06:00
|
|
|
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)
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
WARN("Map for indicator %s redefined\n",
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, old->name));
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION("Using %s definition for duplicate fields\n",
|
2009-03-27 07:55:32 -06:00
|
|
|
(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");
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION("Map for indicator %s not compiled\n",
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, new->name));
|
2009-03-27 07:55:32 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*old = *new;
|
|
|
|
old->defs.next = NULL;
|
|
|
|
if (last)
|
|
|
|
{
|
|
|
|
last->defs.next = &old->defs;
|
|
|
|
return oldLEDs;
|
|
|
|
}
|
|
|
|
return old;
|
|
|
|
}
|
|
|
|
|
2012-03-02 08:40:19 -07:00
|
|
|
static const LookupEntry modComponentNames[] = {
|
|
|
|
{"base", XkbIM_UseBase},
|
|
|
|
{"latched", XkbIM_UseLatched},
|
|
|
|
{"locked", XkbIM_UseLocked},
|
|
|
|
{"effective", XkbIM_UseEffective},
|
|
|
|
{"compat", XkbIM_UseCompat},
|
|
|
|
{"any", XkbIM_UseAnyMods},
|
|
|
|
{"none", 0},
|
2009-03-27 07:55:32 -06:00
|
|
|
{NULL, 0}
|
|
|
|
};
|
2012-03-02 08:40:19 -07:00
|
|
|
static const LookupEntry groupComponentNames[] = {
|
|
|
|
{"base", XkbIM_UseBase},
|
|
|
|
{"latched", XkbIM_UseLatched},
|
|
|
|
{"locked", XkbIM_UseLocked},
|
|
|
|
{"effective", XkbIM_UseEffective},
|
|
|
|
{"any", XkbIM_UseAnyGroup},
|
|
|
|
{"none", 0},
|
2009-03-27 07:55:32 -06:00
|
|
|
{NULL, 0}
|
|
|
|
};
|
|
|
|
|
2012-03-02 08:40:19 -07:00
|
|
|
static const LookupEntry groupNames[] = {
|
|
|
|
{"group1", 0x01},
|
|
|
|
{"group2", 0x02},
|
|
|
|
{"group3", 0x04},
|
|
|
|
{"group4", 0x08},
|
|
|
|
{"group5", 0x10},
|
|
|
|
{"group6", 0x20},
|
|
|
|
{"group7", 0x40},
|
|
|
|
{"group8", 0x80},
|
|
|
|
{"none", 0x00},
|
|
|
|
{"all", 0xff},
|
2012-02-20 09:35:39 -07:00
|
|
|
{NULL, 0}
|
|
|
|
};
|
|
|
|
|
2009-03-27 07:55:32 -06:00
|
|
|
int
|
2012-05-09 08:15:30 -06:00
|
|
|
SetIndicatorMapField(LEDInfo *led, struct xkb_keymap *keymap,
|
|
|
|
char *field, ExprDef *arrayNdx, ExprDef *value)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
ExprResult rtrn;
|
2012-04-05 18:38:55 -06:00
|
|
|
bool ok;
|
2009-03-27 07:55:32 -06:00
|
|
|
|
2012-04-05 18:38:55 -06:00
|
|
|
ok = true;
|
2012-03-23 16:26:12 -06:00
|
|
|
if ((strcasecmp(field, "modifiers") == 0) ||
|
|
|
|
(strcasecmp(field, "mods") == 0))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 08:15:30 -06:00
|
|
|
if (!ExprResolveVModMask(value, &rtrn, keymap))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field, "modifier mask");
|
2009-03-27 07:55:32 -06:00
|
|
|
led->real_mods = rtrn.uval & 0xff;
|
|
|
|
led->vmods = (rtrn.uval >> 8) & 0xff;
|
|
|
|
led->defs.defined |= _LED_Mods;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if (strcasecmp(field, "groups") == 0)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveMask(keymap->ctx, value, &rtrn, groupNames))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field, "group mask");
|
2009-03-27 07:55:32 -06:00
|
|
|
led->groups = rtrn.uval;
|
|
|
|
led->defs.defined |= _LED_Groups;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if ((strcasecmp(field, "controls") == 0) ||
|
|
|
|
(strcasecmp(field, "ctrls") == 0))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveMask(keymap->ctx, value, &rtrn, ctrlNames))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field,
|
2009-03-27 07:55:32 -06:00
|
|
|
"controls mask");
|
|
|
|
led->ctrls = rtrn.uval;
|
|
|
|
led->defs.defined |= _LED_Ctrls;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if (strcasecmp(field, "allowexplicit") == 0)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveBoolean(keymap->ctx, value, &rtrn))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field, "boolean");
|
2009-03-27 07:55:32 -06:00
|
|
|
if (rtrn.uval)
|
|
|
|
led->flags &= ~XkbIM_NoExplicit;
|
|
|
|
else
|
|
|
|
led->flags |= XkbIM_NoExplicit;
|
|
|
|
led->defs.defined |= _LED_Explicit;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if ((strcasecmp(field, "whichmodstate") == 0) ||
|
|
|
|
(strcasecmp(field, "whichmodifierstate") == 0))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveMask(keymap->ctx, value, &rtrn, modComponentNames))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field,
|
2009-03-27 07:55:32 -06:00
|
|
|
"mask of modifier state components");
|
|
|
|
}
|
|
|
|
led->which_mods = rtrn.uval;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if (strcasecmp(field, "whichgroupstate") == 0)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveMask(keymap->ctx, value, &rtrn, groupComponentNames))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field,
|
2009-03-27 07:55:32 -06:00
|
|
|
"mask of group state components");
|
|
|
|
}
|
|
|
|
led->which_groups = rtrn.uval;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if ((strcasecmp(field, "driveskbd") == 0) ||
|
|
|
|
(strcasecmp(field, "driveskeyboard") == 0) ||
|
|
|
|
(strcasecmp(field, "leddriveskbd") == 0) ||
|
|
|
|
(strcasecmp(field, "leddriveskeyboard") == 0) ||
|
|
|
|
(strcasecmp(field, "indicatordriveskbd") == 0) ||
|
|
|
|
(strcasecmp(field, "indicatordriveskeyboard") == 0))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveBoolean(keymap->ctx, value, &rtrn))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field, "boolean");
|
2009-03-27 07:55:32 -06:00
|
|
|
if (rtrn.uval)
|
|
|
|
led->flags |= XkbIM_LEDDrivesKB;
|
|
|
|
else
|
|
|
|
led->flags &= ~XkbIM_LEDDrivesKB;
|
|
|
|
led->defs.defined |= _LED_DrivesKbd;
|
|
|
|
}
|
2012-03-23 16:26:12 -06:00
|
|
|
else if (strcasecmp(field, "index") == 0)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (arrayNdx != NULL)
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorNotArray(keymap, led, field);
|
2012-05-09 06:03:11 -06:00
|
|
|
if (!ExprResolveInteger(keymap->ctx, value, &rtrn))
|
2012-05-09 04:50:05 -06:00
|
|
|
return ReportIndicatorBadType(keymap, led, field,
|
2009-03-27 07:55:32 -06:00
|
|
|
"indicator index");
|
|
|
|
if ((rtrn.uval < 1) || (rtrn.uval > 32))
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
ERROR("Illegal indicator index %d (range 1..%d)\n",
|
2009-03-27 07:55:32 -06:00
|
|
|
rtrn.uval, XkbNumIndicators);
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION("Index definition for %s indicator ignored\n",
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name));
|
2012-04-05 18:38:55 -06:00
|
|
|
return false;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
led->indicator = rtrn.uval;
|
|
|
|
led->defs.defined |= _LED_Index;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
ERROR("Unknown field %s in map for %s indicator\n", field,
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name));
|
2009-03-27 07:55:32 -06:00
|
|
|
ACTION("Definition ignored\n");
|
2012-04-05 18:38:55 -06:00
|
|
|
ok = false;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
LEDInfo *
|
2012-05-09 08:15:30 -06:00
|
|
|
HandleIndicatorMapDef(IndicatorMapDef *def, struct xkb_keymap *keymap,
|
|
|
|
LEDInfo *dflt, LEDInfo *oldLEDs, unsigned merge)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
LEDInfo led, *rtrn;
|
|
|
|
VarDef *var;
|
2012-04-05 18:38:55 -06:00
|
|
|
bool ok;
|
2009-03-27 07:55:32 -06:00
|
|
|
|
|
|
|
if (def->merge != MergeDefault)
|
|
|
|
merge = def->merge;
|
|
|
|
|
|
|
|
led = *dflt;
|
|
|
|
led.defs.merge = merge;
|
|
|
|
led.name = def->name;
|
|
|
|
|
2012-04-05 18:38:55 -06:00
|
|
|
ok = true;
|
2009-03-27 07:55:32 -06:00
|
|
|
for (var = def->body; var != NULL; var = (VarDef *) var->common.next)
|
|
|
|
{
|
|
|
|
ExprResult elem, field;
|
|
|
|
ExprDef *arrayNdx;
|
2012-05-09 03:01:03 -06:00
|
|
|
if (!ExprResolveLhs(keymap, var->name, &elem, &field, &arrayNdx))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-04-05 18:38:55 -06:00
|
|
|
ok = false;
|
2009-03-27 07:55:32 -06:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (elem.str != NULL)
|
|
|
|
{
|
2009-03-31 08:21:20 -06:00
|
|
|
ERROR
|
2009-03-27 07:55:32 -06:00
|
|
|
("Cannot set defaults for \"%s\" element in indicator map\n",
|
|
|
|
elem.str);
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION("Assignment to %s.%s ignored\n", elem.str, field.str);
|
2012-04-05 18:38:55 -06:00
|
|
|
ok = false;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
ok = SetIndicatorMapField(&led, keymap, field.str, arrayNdx,
|
2009-03-27 07:55:32 -06:00
|
|
|
var->value) && ok;
|
|
|
|
}
|
2010-06-15 08:23:23 -06:00
|
|
|
free(elem.str);
|
|
|
|
free(field.str);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
if (ok)
|
|
|
|
{
|
2012-05-09 04:50:05 -06:00
|
|
|
rtrn = AddIndicatorMap(keymap, oldLEDs, &led);
|
2009-03-27 07:55:32 -06:00
|
|
|
return rtrn;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-04-05 18:38:55 -06:00
|
|
|
bool
|
2012-05-09 08:15:30 -06:00
|
|
|
CopyIndicatorMapDefs(struct xkb_keymap *keymap, LEDInfo *leds,
|
|
|
|
LEDInfo **unboundRtrn)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
LEDInfo *led, *next;
|
|
|
|
LEDInfo *unbound, *last;
|
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (XkbcAllocNames(keymap, XkbIndicatorNamesMask, 0) != Success)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
WSGO("Couldn't allocate names\n");
|
|
|
|
ACTION("Indicator names may be incorrect\n");
|
|
|
|
}
|
2012-05-09 08:15:30 -06:00
|
|
|
if (XkbcAllocIndicatorMaps(keymap) != Success)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
WSGO("Can't allocate indicator maps\n");
|
|
|
|
ACTION("Indicator map definitions may be lost\n");
|
2012-04-05 18:38:55 -06:00
|
|
|
return false;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
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;
|
2012-05-09 08:15:30 -06:00
|
|
|
if ((led->indicator == _LED_NotBound) || (!keymap->indicators))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
if (unboundRtrn != NULL)
|
|
|
|
{
|
|
|
|
led->defs.next = NULL;
|
|
|
|
if (last != NULL)
|
|
|
|
last->defs.next = (CommonInfo *) led;
|
|
|
|
else
|
|
|
|
unbound = led;
|
|
|
|
last = led;
|
|
|
|
}
|
|
|
|
else
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-02-29 11:25:11 -07:00
|
|
|
struct xkb_indicator_map * im;
|
2012-05-09 08:15:30 -06:00
|
|
|
im = &keymap->indicators->maps[led->indicator - 1];
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->names != NULL)
|
2012-03-09 11:53:47 -07:00
|
|
|
{
|
2012-06-08 00:25:38 -06:00
|
|
|
free(keymap->names->indicators[led->indicator - 1]);
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->names->indicators[led->indicator-1] =
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_strdup(keymap->ctx, led->name);
|
2012-03-09 11:53:47 -07:00
|
|
|
}
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (unboundRtrn != NULL)
|
|
|
|
{
|
|
|
|
*unboundRtrn = unbound;
|
|
|
|
}
|
2012-04-05 18:38:55 -06:00
|
|
|
return true;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
|
2012-04-05 18:38:55 -06:00
|
|
|
bool
|
2012-05-09 08:15:30 -06:00
|
|
|
BindIndicators(struct xkb_keymap *keymap, bool force, LEDInfo *unbound,
|
2009-03-27 20:54:50 -06:00
|
|
|
LEDInfo **unboundRtrn)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-02-29 11:25:11 -07:00
|
|
|
int i;
|
|
|
|
LEDInfo *led, *next, *last;
|
2009-03-27 07:55:32 -06:00
|
|
|
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->names != NULL)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
for (led = unbound; led != NULL; led = (LEDInfo *) led->defs.next)
|
|
|
|
{
|
|
|
|
if (led->indicator == _LED_NotBound)
|
|
|
|
{
|
|
|
|
for (i = 0; i < XkbNumIndicators; i++)
|
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->names->indicators[i] &&
|
|
|
|
strcmp(keymap->names->indicators[i],
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name)) == 0)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
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++)
|
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if (keymap->names->indicators[i] == NULL)
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
keymap->names->indicators[i] =
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_strdup(keymap->ctx, led->name);
|
2009-03-27 07:55:32 -06:00
|
|
|
led->indicator = i + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (led->indicator == _LED_NotBound)
|
|
|
|
{
|
|
|
|
ERROR("No unnamed indicators found\n");
|
2009-03-31 08:21:20 -06:00
|
|
|
ACTION
|
2009-03-27 07:55:32 -06:00
|
|
|
("Virtual indicator map \"%s\" not bound\n",
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name));
|
2009-03-27 07:55:32 -06:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (last = NULL, led = unbound; led != NULL; led = next)
|
|
|
|
{
|
|
|
|
next = (LEDInfo *) led->defs.next;
|
|
|
|
if (led->indicator == _LED_NotBound)
|
|
|
|
{
|
|
|
|
if (force)
|
|
|
|
{
|
|
|
|
unbound = next;
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (last)
|
|
|
|
last->defs.next = &led->defs;
|
|
|
|
else
|
|
|
|
unbound = led;
|
|
|
|
last = led;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
if ((keymap->names != NULL) &&
|
|
|
|
(strcmp(keymap->names->indicators[led->indicator - 1],
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name)) != 0))
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
2012-05-09 08:15:30 -06:00
|
|
|
const char *old = keymap->names->indicators[led->indicator - 1];
|
2009-03-31 08:21:20 -06:00
|
|
|
ERROR("Multiple names bound to indicator %d\n",
|
2009-03-27 07:55:32 -06:00
|
|
|
(unsigned int) led->indicator);
|
2012-05-09 04:50:05 -06:00
|
|
|
ACTION("Using %s, ignoring %s\n", old,
|
2012-05-09 06:03:11 -06:00
|
|
|
xkb_atom_text(keymap->ctx, led->name));
|
2009-03-27 07:55:32 -06:00
|
|
|
led->indicator = _LED_NotBound;
|
|
|
|
if (force)
|
|
|
|
{
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
unbound = next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (last)
|
|
|
|
last->defs.next = &led->defs;
|
|
|
|
else
|
|
|
|
unbound = led;
|
|
|
|
last = led;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-01 12:35:24 -06:00
|
|
|
struct xkb_indicator_map * map;
|
2012-05-09 08:15:30 -06:00
|
|
|
map = &keymap->indicators->maps[led->indicator - 1];
|
2009-03-27 07:55:32 -06:00
|
|
|
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;
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (unboundRtrn)
|
|
|
|
{
|
|
|
|
*unboundRtrn = unbound;
|
|
|
|
}
|
2012-02-24 07:03:44 -07:00
|
|
|
else
|
2009-03-27 07:55:32 -06:00
|
|
|
{
|
|
|
|
for (led = unbound; led != NULL; led = next)
|
|
|
|
{
|
2012-02-24 07:03:44 -07:00
|
|
|
next = led ? (LEDInfo *) led->defs.next : NULL;
|
2010-06-28 04:58:01 -06:00
|
|
|
free(led);
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|
|
|
|
}
|
2012-04-05 18:38:55 -06:00
|
|
|
return true;
|
2009-03-27 07:55:32 -06:00
|
|
|
}
|