#include "keymap.h"
+#include "contextP.h"
#include "ksyms.h"
#include "modifiers.h"
int
-lk_add_map(struct keymap *kmap, int i)
+lk_map_exists(struct lk_ctx *ctx, unsigned int k_table)
{
- if (i < 0 || i >= MAX_NR_KEYMAPS) {
- ERR(kmap, _("lk_add_map called with bad index %d"), i);
- return -1;
- }
+ return (lk_array_get_ptr(ctx->keymap, k_table) != NULL);
+}
- if (kmap->defining[i])
+int
+lk_get_keys_total(struct lk_ctx *ctx, unsigned int k_table)
+{
+ struct lk_array *map;
+ map = lk_array_get_ptr(ctx->keymap, k_table);
+ if (!map) {
return 0;
+ }
+ return map->total;
+}
+
+int
+lk_key_exists(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index)
+{
+ struct lk_array *map;
+ unsigned int *key;
- kmap->defining[i] = i + 1;
+ map = lk_array_get_ptr(ctx->keymap, k_table);
+ if (!map) {
+ return 0;
+ }
- if (kmap->max_keymap <= i)
- kmap->max_keymap = i + 1;
+ key = lk_array_get(map, k_index);
+ if (!key) {
+ return 0;
+ }
- return 0;
+ return (*key > 0);
}
int
-lk_get_key(struct keymap *kmap, int k_table, int k_index)
+lk_add_map(struct lk_ctx *ctx, unsigned int k_table)
{
- if (k_index < 0 || k_index >= NR_KEYS) {
- ERR(kmap, _("lk_get_key called with bad index %d"), k_index);
- return -1;
+ struct lk_array *keys;
+
+ if (lk_map_exists(ctx, k_table)) {
+ return 0;
}
- if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
- ERR(kmap, _("lk_get_key called with bad table %d"), k_table);
+ keys = malloc(sizeof(struct lk_array));
+ if (!keys) {
+ ERR(ctx, _("out of memory"));
return -1;
}
- if (!(kmap->keymap_was_set[k_table]))
+ lk_array_init(keys, sizeof(unsigned int), 0);
+
+ if (lk_array_set(ctx->keymap, k_table, &keys) < 0) {
+ free(keys);
+ ERR(ctx, _("out of memory"));
return -1;
+ }
- return (kmap->key_map[k_table])[k_index];
+ return 0;
}
int
-lk_remove_key(struct keymap *kmap, int k_index, int k_table)
+lk_get_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index)
{
- /* roughly: addkey(k_index, k_table, K_HOLE); */
+ struct lk_array *map;
+ unsigned int *key;
- if (k_index < 0 || k_index >= NR_KEYS) {
- ERR(kmap, _("lk_remove_key called with bad index %d"), k_index);
+ map = lk_array_get_ptr(ctx->keymap, k_table);
+ if (!map) {
+ ERR(ctx, _("unable to get keymap %d"), k_table);
return -1;
}
- if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
- ERR(kmap, _("lk_remove_key called with bad table %d"), k_table);
+ key = lk_array_get(map, k_index);
+ if (!key || *key == 0) {
+ return K_HOLE;
+ }
+
+ return (*key)-1;
+}
+
+int
+lk_del_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index)
+{
+ struct lk_array *map;
+
+ map = lk_array_get_ptr(ctx->keymap, k_table);
+ if (!map) {
+ ERR(ctx, _("unable to get keymap %d"), k_table);
return -1;
}
- if (kmap->key_map[k_table])
- (kmap->key_map[k_table])[k_index] = K_HOLE;
+ if (!lk_array_exists(map, k_index))
+ return 0;
- if (kmap->keymap_was_set[k_table])
- (kmap->keymap_was_set[k_table])[k_index] = 0;
+ if (lk_array_unset(map, k_index) < 0) {
+ ERR(ctx, _("unable to unset key %d for table %d"),
+ k_index, k_table);
+ return -1;
+ }
return 0;
}
int
-lk_add_key(struct keymap *kmap, int k_index, int k_table, int keycode)
+lk_add_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index, int keycode)
{
- int i;
+ struct lk_array *map;
+ unsigned int code = keycode + 1;
if (keycode == CODE_FOR_UNKNOWN_KSYM) {
/* is safer not to be silent in this case,
* it can be caused by coding errors as well. */
- ERR(kmap, _("lk_add_key called with bad keycode %d"), keycode);
- return -1;
- }
-
- if (k_index < 0 || k_index >= NR_KEYS) {
- ERR(kmap, _("lk_add_key called with bad index %d"), k_index);
- return -1;
- }
-
- if (k_table < 0 || k_table >= MAX_NR_KEYMAPS) {
- ERR(kmap, _("lk_add_key called with bad table %d"), k_table);
+ ERR(ctx, _("lk_add_key called with bad keycode %d"), keycode);
return -1;
}
if (!k_index && keycode == K_NOSUCHMAP)
return 0;
- if (!kmap->defining[k_table]) {
- if (kmap->keymaps_line_seen) {
- ERR(kmap, _("adding map %d violates explicit keymaps line"),
+ map = lk_array_get_ptr(ctx->keymap, k_table);
+ if (!map) {
+ if (ctx->keywords & LK_KEYWORD_KEYMAPS) {
+ ERR(ctx, _("adding map %d violates explicit keymaps line"),
k_table);
return -1;
}
- if (lk_add_map(kmap, k_table) < 0)
- return -1;
- }
-
- if (!kmap->key_map[k_table]) {
- kmap->key_map[k_table] = (u_short *)malloc(NR_KEYS * sizeof(u_short));
-
- if (!kmap->key_map[k_table]) {
- ERR(kmap, _("out of memory"));
+ if (lk_add_map(ctx, k_table) < 0)
return -1;
- }
-
- for (i = 0; i < NR_KEYS; i++)
- (kmap->key_map[k_table])[i] = K_HOLE;
}
- if (!kmap->keymap_was_set[k_table]) {
- kmap->keymap_was_set[k_table] = (char *)malloc(NR_KEYS);
+ if ((ctx->keywords & LK_KEYWORD_ALTISMETA) && keycode == K_HOLE &&
+ lk_key_exists(ctx, k_table, k_index))
+ return 0;
- if (!kmap->key_map[k_table]) {
- ERR(kmap, _("out of memory"));
- return -1;
- }
+ map = lk_array_get_ptr(ctx->keymap, k_table);
- for (i = 0; i < NR_KEYS; i++)
- (kmap->keymap_was_set[k_table])[i] = 0;
+ if (lk_array_set(map, k_index, &code) < 0) {
+ ERR(ctx, _("unable to set key %d for table %d"),
+ k_index, k_table);
+ return -1;
}
- if (kmap->alt_is_meta && keycode == K_HOLE
- && (kmap->keymap_was_set[k_table])[k_index])
- return 0;
-
- (kmap->key_map[k_table])[k_index] = keycode;
- (kmap->keymap_was_set[k_table])[k_index] = 1;
-
- if (kmap->alt_is_meta) {
- int alttable = k_table | M_ALT;
+ if (ctx->keywords & LK_KEYWORD_ALTISMETA) {
+ unsigned int alttable = k_table | M_ALT;
int type = KTYP(keycode);
int val = KVAL(keycode);
- if (alttable != k_table && kmap->defining[alttable] &&
- (!kmap->keymap_was_set[alttable] ||
- !(kmap->keymap_was_set[alttable])[k_index]) &&
- (type == KT_LATIN || type == KT_LETTER) && val < 128) {
- if (lk_add_key(kmap, k_index, alttable, K(KT_META, val)) < 0)
+ if (alttable != k_table && lk_map_exists(ctx, alttable) &&
+ !lk_key_exists(ctx, alttable, k_index) &&
+ (type == KT_LATIN || type == KT_LETTER) &&
+ val < 128) {
+ if (lk_add_key(ctx, alttable, k_index, K(KT_META, val)) < 0)
return -1;
}
}
+
return 0;
}
int
-lk_get_func(struct keymap *kmap, struct kbsentry *kbs)
+lk_get_func(struct lk_ctx *ctx, struct kbsentry *kbs)
{
- int x = kbs->kb_func;
-
- if (x >= MAX_NR_FUNC) {
- ERR(kmap, _("bad index %d"), x);
- return -1;
- }
+ char *s;
- if(!(kmap->func_table[x])) {
- ERR(kmap, _("func %d not allocated"), x);
+ s = lk_array_get_ptr(ctx->func_table, kbs->kb_func);
+ if (!s) {
+ ERR(ctx, _("func %d not allocated"), kbs->kb_func);
return -1;
}
- strncpy((char *)kbs->kb_string, kmap->func_table[x],
- sizeof(kbs->kb_string));
+ strncpy((char *)kbs->kb_string, s, sizeof(kbs->kb_string));
kbs->kb_string[sizeof(kbs->kb_string) - 1] = 0;
return 0;
int
-lk_add_func(struct keymap *kmap, struct kbsentry kbs)
+lk_add_func(struct lk_ctx *ctx, struct kbsentry kbs)
{
- int x;
+ char *s;
- x = kbs.kb_func;
+ s = lk_array_get_ptr(ctx->func_table, kbs.kb_func);
+ if (s)
+ free(s);
- if (x >= MAX_NR_FUNC) {
- ERR(kmap, _("bad func %d"), kbs.kb_func);
+ s = strdup((char *)kbs.kb_string);
+
+ if (lk_array_set(ctx->func_table, kbs.kb_func, &s) < 0) {
+ free(s);
+ ERR(ctx, _("out of memory"));
return -1;
}
- if(kmap->func_table[x]) {
- free(kmap->func_table[x]);
- kmap->func_table[x] = NULL;
- }
+ return 0;
+}
- kmap->func_table[x] = strdup((char *)kbs.kb_string);
+int
+lk_get_diacr(struct lk_ctx *ctx, unsigned int index, struct lk_kbdiacr *dcr)
+{
+ struct lk_kbdiacr *ptr;
- if (!kmap->func_table[x]) {
- ERR(kmap, _("out of memory"));
+ ptr = lk_array_get_ptr(ctx->accent_table, index);
+ if (!ptr) {
+ ERR(ctx, _("Index %d in the accent table does not exist"), index);
return -1;
}
+ dcr->diacr = ptr->diacr;
+ dcr->base = ptr->base;
+ dcr->result = ptr->result;
+
return 0;
}
int
-lk_add_diacr(struct keymap *kmap, unsigned int diacr, unsigned int base, unsigned int res)
+lk_add_diacr(struct lk_ctx *ctx, struct lk_kbdiacr *dcr)
{
- accent_entry *ptr;
+ struct lk_kbdiacr *ptr;
- if (kmap->accent_table_size == MAX_DIACR) {
- ERR(kmap, _("table overflow"));
+ ptr = malloc(sizeof(struct lk_kbdiacr));
+ if (!ptr) {
+ ERR(ctx, _("out of memory"));
return -1;
}
- ptr = &(kmap->accent_table[kmap->accent_table_size++]);
- ptr->diacr = diacr;
- ptr->base = base;
- ptr->result = res;
+ ptr->diacr = dcr->diacr;
+ ptr->base = dcr->base;
+ ptr->result = dcr->result;
+
+ lk_array_append(ctx->accent_table, &ptr);
return 0;
}
int
-lk_add_compose(struct keymap *kmap,
- unsigned int diacr,
- unsigned int base,
- unsigned int res)
+lk_add_compose(struct lk_ctx *ctx, struct lk_kbdiacr *dcr)
{
+ struct lk_kbdiacr dcr0;
int direction = TO_8BIT;
#ifdef KDSKBDIACRUC
- if (kmap->prefer_unicode)
+ if (ctx->flags & LK_FLAG_PREFER_UNICODE)
direction = TO_UNICODE;
#endif
- return lk_add_diacr(kmap,
- convert_code(kmap, diacr, direction),
- convert_code(kmap, base, direction),
- convert_code(kmap, res, direction)
- );
+
+ dcr0.diacr = convert_code(ctx, dcr->diacr, direction);
+ dcr0.base = convert_code(ctx, dcr->base, direction);
+ dcr0.result = convert_code(ctx, dcr->result, direction);
+
+ return lk_add_diacr(ctx, &dcr0);
}
static int
-do_constant_key(struct keymap *kmap, int i, u_short key)
+do_constant_key(struct lk_ctx *ctx, int i, u_short key)
{
- int typ, val, j;
+ int typ, val;
+ unsigned int j;
typ = KTYP(key);
val = KVAL(key);
for (j = 8; j < 16; j++)
defs[j] = K(KT_META, KVAL(defs[j - 8]));
- for (j = 0; j < kmap->max_keymap; j++) {
- if (!kmap->defining[j])
+ for (j = 0; j < ctx->keymap->total; j++) {
+ if (!lk_map_exists(ctx, j))
continue;
- if (j > 0 &&
- kmap->keymap_was_set[j] && (kmap->keymap_was_set[j])[i])
+ if (j > 0 && lk_key_exists(ctx, j, i))
continue;
- if (lk_add_key(kmap, i, j, defs[j % 16]) < 0)
+ if (lk_add_key(ctx, j, i, defs[j % 16]) < 0)
return -1;
}
} else {
/* do this also for keys like Escape,
as promised in the man page */
- for (j = 1; j < kmap->max_keymap; j++) {
- if (!kmap->defining[j])
+ for (j = 1; j < ctx->keymap->total; j++) {
+ if (!lk_map_exists(ctx, j))
continue;
- if (kmap->keymap_was_set[j] && (kmap->keymap_was_set[j])[i])
+ if (lk_key_exists(ctx, j, i))
continue;
- if (lk_add_key(kmap, i, j, key) < 0)
+ if (lk_add_key(ctx, j, i, key) < 0)
return -1;
}
}
}
int
-lk_add_constants(struct keymap *kmap)
+lk_add_constants(struct lk_ctx *ctx)
{
- int i, r0 = 0;
+ unsigned int i, r0 = 0;
- if (kmap->keymaps_line_seen) {
- while (r0 < kmap->max_keymap && !kmap->defining[r0])
+ if (ctx->keywords & LK_KEYWORD_KEYMAPS) {
+ while (r0 < ctx->keymap->total && !lk_map_exists(ctx, r0))
r0++;
}
- for (i = 0; i < NR_KEYS; i++) {
+ for (i = 0; i < ctx->key_constant->total; i++) {
+ char *constant;
u_short key;
- if (!kmap->key_is_constant[i])
+ constant = lk_array_get(ctx->key_constant, i);
+ if (!constant || !(*constant))
continue;
- if (!kmap->key_map[r0]) {
- ERR(kmap, _("impossible error in lk_add_constants"));
+ if (!lk_map_exists(ctx, r0)) {
+ ERR(ctx, _("impossible error in lk_add_constants"));
return -1;
}
- key = lk_get_key(kmap, r0, i);
+ key = lk_get_key(ctx, r0, i);
- if (do_constant_key(kmap, i, key) < 0)
+ if (do_constant_key(ctx, i, key) < 0)
return -1;
}
return 0;