keycodes: use array for indicator names instead of list

Using a simple array here to mirror keymap->indicator_names makes much
more sense, and is simpler.

Signed-off-by: Ran Benita <ran234@gmail.com>
master
Ran Benita 2012-08-31 11:40:35 +03:00
parent be78b8264d
commit 518aff6d7b
1 changed files with 48 additions and 85 deletions

View File

@ -130,9 +130,7 @@ typedef struct _AliasInfo {
typedef struct _IndicatorNameInfo { typedef struct _IndicatorNameInfo {
enum merge_mode merge; enum merge_mode merge;
unsigned file_id; unsigned file_id;
struct list entry;
xkb_led_index_t ndx;
xkb_atom_t name; xkb_atom_t name;
} IndicatorNameInfo; } IndicatorNameInfo;
@ -148,7 +146,7 @@ typedef struct _KeyNamesInfo {
xkb_keycode_t explicitMax; xkb_keycode_t explicitMax;
darray(unsigned long) names; darray(unsigned long) names;
darray(unsigned int) files; darray(unsigned int) files;
struct list leds; IndicatorNameInfo indicator_names[XkbNumIndicators];
struct list aliases; struct list aliases;
struct xkb_context *ctx; struct xkb_context *ctx;
@ -175,70 +173,39 @@ InitAliasInfo(AliasInfo *info, enum merge_mode merge, unsigned file_id,
info->real = KeyNameToLong(real); info->real = KeyNameToLong(real);
} }
static void
InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
{
ii->merge = info->merge;
ii->file_id = info->file_id;
ii->ndx = 0;
ii->name = XKB_ATOM_NONE;
}
static IndicatorNameInfo * static IndicatorNameInfo *
NextIndicatorName(KeyNamesInfo * info) FindIndicatorByName(KeyNamesInfo *info, xkb_atom_t name,
xkb_led_index_t *idx_out)
{ {
IndicatorNameInfo *ii; xkb_led_index_t idx;
ii = malloc(sizeof(*ii)); for (idx = 0; idx < XkbNumIndicators; idx++) {
if (!ii) if (info->indicator_names[idx].name == name) {
return NULL; *idx_out = idx;
return &info->indicator_names[idx];
InitIndicatorNameInfo(ii, info);
list_append(&ii->entry, &info->leds);
return ii;
} }
static IndicatorNameInfo *
FindIndicatorByIndex(KeyNamesInfo * info, xkb_led_index_t ndx)
{
IndicatorNameInfo *old;
list_foreach(old, &info->leds, entry)
if (old->ndx == ndx)
return old;
return NULL;
} }
static IndicatorNameInfo *
FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
{
IndicatorNameInfo *old;
list_foreach(old, &info->leds, entry)
if (old->name == name)
return old;
return NULL; return NULL;
} }
static bool static bool
AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge, AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
IndicatorNameInfo *new) IndicatorNameInfo *new, xkb_led_index_t new_idx)
{ {
xkb_led_index_t old_idx;
IndicatorNameInfo *old; IndicatorNameInfo *old;
bool replace, report; bool replace, report;
int verbosity = xkb_get_log_verbosity(info->ctx); int verbosity = xkb_get_log_verbosity(info->ctx);
replace = (merge == MERGE_REPLACE) || (merge == MERGE_OVERRIDE); replace = (merge == MERGE_REPLACE) || (merge == MERGE_OVERRIDE);
old = FindIndicatorByName(info, new->name); old = FindIndicatorByName(info, new->name, &old_idx);
if (old) { if (old) {
report = ((old->file_id == new->file_id && verbosity > 0) || report = ((old->file_id == new->file_id && verbosity > 0) ||
verbosity > 9); verbosity > 9);
if (old->ndx == new->ndx) { if (old_idx == new_idx) {
if (report) if (report)
log_warn(info->ctx, "Multiple indicators named %s; " log_warn(info->ctx, "Multiple indicators named %s; "
"Identical definitions ignored\n", "Identical definitions ignored\n",
@ -250,29 +217,31 @@ AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
log_warn(info->ctx, "Multiple indicators named %s; " log_warn(info->ctx, "Multiple indicators named %s; "
"Using %d, ignoring %d\n", "Using %d, ignoring %d\n",
xkb_atom_text(info->ctx, new->name), xkb_atom_text(info->ctx, new->name),
(replace ? old->ndx : new->ndx), (replace ? old_idx + 1 : new_idx + 1),
(replace ? new->ndx : old->ndx)); (replace ? new_idx + 1 : old_idx + 1));
if (replace) { /*
list_del(&old->entry); * XXX: If in the next check we ignore new, than we will have
free(old); * deleted this old for nothing!
} */
if (replace)
memset(old, 0, sizeof(*old));
} }
old = FindIndicatorByIndex(info, new->ndx); old = &info->indicator_names[new_idx];
if (old) { if (old->name != XKB_ATOM_NONE) {
report = ((old->file_id == new->file_id && verbosity > 0) || report = ((old->file_id == new->file_id && verbosity > 0) ||
verbosity > 9); verbosity > 9);
if (old->name == new->name) { if (old->name == new->name) {
if (report) if (report)
log_warn(info->ctx, "Multiple names for indicator %d; " log_warn(info->ctx, "Multiple names for indicator %d; "
"Identical definitions ignored\n", new->ndx); "Identical definitions ignored\n", new_idx + 1);
} }
else if (replace) { else if (replace) {
if (report) if (report)
log_warn(info->ctx, "Multiple names for indicator %d; " log_warn(info->ctx, "Multiple names for indicator %d; "
"Using %s, ignoring %s\n", new->ndx, "Using %s, ignoring %s\n", new_idx + 1,
xkb_atom_text(info->ctx, new->name), xkb_atom_text(info->ctx, new->name),
xkb_atom_text(info->ctx, old->name)); xkb_atom_text(info->ctx, old->name));
old->name = new->name; old->name = new->name;
@ -280,7 +249,7 @@ AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
else { else {
if (report) if (report)
log_warn(info->ctx, "Multiple names for indicator %d; " log_warn(info->ctx, "Multiple names for indicator %d; "
"Using %s, ignoring %s\n", new->ndx, "Using %s, ignoring %s\n", new_idx + 1,
xkb_atom_text(info->ctx, old->name), xkb_atom_text(info->ctx, old->name),
xkb_atom_text(info->ctx, new->name)); xkb_atom_text(info->ctx, new->name));
} }
@ -288,16 +257,7 @@ AddIndicatorName(KeyNamesInfo *info, enum merge_mode merge,
return true; return true;
} }
old = new; info->indicator_names[new_idx] = *new;
new = NextIndicatorName(info);
if (!new) {
log_wsgo(info->ctx,
"Couldn't allocate name for indicator %d; Ignored\n",
old->ndx);
return false;
}
new->name = old->name;
new->ndx = old->ndx;
return true; return true;
} }
@ -305,7 +265,6 @@ static void
ClearKeyNamesInfo(KeyNamesInfo * info) ClearKeyNamesInfo(KeyNamesInfo * info)
{ {
AliasInfo *alias, *next_alias; AliasInfo *alias, *next_alias;
IndicatorNameInfo *ii, *next_ii;
free(info->name); free(info->name);
info->name = NULL; info->name = NULL;
@ -314,9 +273,7 @@ ClearKeyNamesInfo(KeyNamesInfo * info)
info->computedMin = XKB_KEYCODE_MAX; info->computedMin = XKB_KEYCODE_MAX;
darray_free(info->names); darray_free(info->names);
darray_free(info->files); darray_free(info->files);
list_foreach_safe(ii, next_ii, &info->leds, entry) memset(info->indicator_names, 0, sizeof(info->indicator_names));
free(ii);
list_init(&info->leds);
list_foreach_safe(alias, next_alias, &info->aliases, entry) list_foreach_safe(alias, next_alias, &info->aliases, entry)
free(alias); free(alias);
list_init(&info->aliases); list_init(&info->aliases);
@ -328,7 +285,6 @@ InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx,
{ {
info->name = NULL; info->name = NULL;
info->merge = MERGE_DEFAULT; info->merge = MERGE_DEFAULT;
list_init(&info->leds);
list_init(&info->aliases); list_init(&info->aliases);
info->file_id = file_id; info->file_id = file_id;
darray_init(info->names); darray_init(info->names);
@ -463,7 +419,7 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
enum merge_mode merge) enum merge_mode merge)
{ {
xkb_keycode_t i; xkb_keycode_t i;
IndicatorNameInfo *led; xkb_led_index_t idx;
if (from->errorCount > 0) { if (from->errorCount > 0) {
into->errorCount += from->errorCount; into->errorCount += from->errorCount;
@ -486,9 +442,13 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
into->errorCount++; into->errorCount++;
} }
list_foreach(led, &from->leds, entry) { for (idx = 0; idx < XkbNumIndicators; idx++) {
IndicatorNameInfo *led = &from->indicator_names[idx];
if (led->name == XKB_ATOM_NONE)
continue;
led->merge = (merge == MERGE_DEFAULT ? led->merge : merge); led->merge = (merge == MERGE_DEFAULT ? led->merge : merge);
if (!AddIndicatorName(into, led->merge, led)) if (!AddIndicatorName(into, led->merge, led, idx))
into->errorCount++; into->errorCount++;
} }
@ -761,8 +721,6 @@ HandleIndicatorNameDef(KeyNamesInfo *info, IndicatorNameDef *def,
return false; return false;
} }
InitIndicatorNameInfo(&ii, info);
if (!ExprResolveString(info->ctx, def->name, &str)) { if (!ExprResolveString(info->ctx, def->name, &str)) {
char buf[20]; char buf[20];
snprintf(buf, sizeof(buf), "%d", def->ndx); snprintf(buf, sizeof(buf), "%d", def->ndx);
@ -771,10 +729,10 @@ HandleIndicatorNameDef(KeyNamesInfo *info, IndicatorNameDef *def,
"string"); "string");
} }
ii.ndx = (xkb_led_index_t) def->ndx; ii.merge = info->merge;
ii.file_id = info->file_id;
ii.name = xkb_atom_intern(info->ctx, str); ii.name = xkb_atom_intern(info->ctx, str);
return AddIndicatorName(info, merge, &ii, def->ndx - 1);
return AddIndicatorName(info, merge, &ii);
} }
/** /**
@ -914,7 +872,7 @@ static bool
CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
{ {
xkb_keycode_t kc; xkb_keycode_t kc;
IndicatorNameInfo *ii; xkb_led_index_t idx;
if (info->explicitMin > 0) if (info->explicitMin > 0)
keymap->min_key_code = info->explicitMin; keymap->min_key_code = info->explicitMin;
@ -933,9 +891,14 @@ CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
keymap->keycodes_section_name = strdup_safe(info->name); keymap->keycodes_section_name = strdup_safe(info->name);
list_foreach(ii, &info->leds, entry) for (idx = 0; idx < XkbNumIndicators; idx++) {
keymap->indicator_names[ii->ndx - 1] = IndicatorNameInfo *led = &info->indicator_names[idx];
xkb_atom_text(keymap->ctx, ii->name); if (led->name == XKB_ATOM_NONE)
continue;
keymap->indicator_names[idx] =
xkb_atom_text(keymap->ctx, led->name);
}
ApplyAliases(info, keymap); ApplyAliases(info, keymap);