int lk_add_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index, int keycode) { 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(ctx, _("lk_add_key called with bad keycode %d"), keycode); return -1; } if (!k_index && keycode == K_NOSUCHMAP) return 0; 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(ctx, k_table) < 0) return -1; } if ((ctx->keywords & LK_KEYWORD_ALTISMETA) && keycode == K_HOLE && lk_key_exists(ctx, k_table, k_index)) return 0; map = lk_array_get_ptr(ctx->keymap, k_table); 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 (ctx->keywords & LK_KEYWORD_ALTISMETA) { unsigned int alttable = k_table | M_ALT; int type = KTYP(keycode); int val = KVAL(keycode); 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_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_get_func(struct lk_ctx *ctx, struct kbsentry *kbs) { char *s; 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, s, sizeof(kbs->kb_string)); kbs->kb_string[sizeof(kbs->kb_string) - 1] = 0; return 0; }
int lk_key_exists(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index) { struct lk_array *map; unsigned int *key; map = lk_array_get_ptr(ctx->keymap, k_table); if (!map) { return 0; } key = lk_array_get(map, k_index); if (!key) { return 0; } return (*key > 0); }
int lk_add_func(struct lk_ctx *ctx, struct kbsentry *kbs) { char *s; s = lk_array_get_ptr(ctx->func_table, kbs->kb_func); if (s) free(s); 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; } return 0; }
int lk_get_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index) { struct lk_array *map; unsigned int *key; map = lk_array_get_ptr(ctx->keymap, k_table); if (!map) { ERR(ctx, _("unable to get keymap %d"), k_table); return -1; } 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 (!lk_array_exists(map, k_index)) return 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; }
static int deffuncs(struct lk_ctx *ctx, int fd) { unsigned int i; int ct = 0; char *ptr, *s; struct kbsentry kbs; for (i = 0; i < MAX_NR_FUNC; i++) { kbs.kb_func = (unsigned char) i; ptr = lk_array_get_ptr(ctx->func_table, i); if (ptr) { strcpy((char *)kbs.kb_string, ptr); if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) { s = ostr(ctx, (char *)kbs.kb_string); if (s == NULL) return -1; ERR(ctx, _("failed to bind string '%s' to function %s"), s, get_sym(ctx, KT_FN, kbs.kb_func)); free(s); } else { ct++; } } else if (ctx->flags & LK_FLAG_CLEAR_STRINGS) { kbs.kb_string[0] = 0; if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs)) { ERR(ctx, _("failed to clear string %s"), get_sym(ctx, KT_FN, kbs.kb_func)); } else { ct++; } } } return ct; }
int lk_func_exists(struct lk_ctx *ctx, unsigned int index) { return (lk_array_get_ptr(ctx->func_table, index) != NULL); }
int lk_map_exists(struct lk_ctx *ctx, unsigned int k_table) { return (lk_array_get_ptr(ctx->keymap, k_table) != NULL); }
static int defdiacs(struct lk_ctx *ctx, int fd) { unsigned int i, j, count; struct lk_kbdiacr *ptr; if (ctx->accent_table->count > MAX_DIACR) { count = MAX_DIACR; ERR(ctx, _("too many compose definitions")); } else { count = (unsigned int) ctx->accent_table->count; } #ifdef KDSKBDIACRUC if (ctx->flags & LK_FLAG_PREFER_UNICODE) { struct kbdiacrsuc kdu; kdu.kb_cnt = count; for (i = 0, j = 0; i < ctx->accent_table->total && j < count; i++) { ptr = lk_array_get_ptr(ctx->accent_table, i); if (!ptr) continue; kdu.kbdiacruc[j].diacr = ptr->diacr; kdu.kbdiacruc[j].base = ptr->base; kdu.kbdiacruc[j].result = ptr->result; j++; } if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu)) { ERR(ctx, "KDSKBDIACRUC: %s", strerror(errno)); return -1; } } else #endif { struct kbdiacrs kd; kd.kb_cnt = count; for (i = 0, j = 0; i < ctx->accent_table->total && j < count; i++) { ptr = lk_array_get_ptr(ctx->accent_table, i); if (!ptr) continue; if (ptr->diacr > UCHAR_MAX || ptr->base > UCHAR_MAX || ptr->result > UCHAR_MAX) { ERR(ctx, "unable to load compose definitions because some of them are too large"); return -1; } kd.kbdiacr[j].diacr = (unsigned char) ptr->diacr; kd.kbdiacr[j].base = (unsigned char) ptr->base; kd.kbdiacr[j].result = (unsigned char) ptr->result; j++; } if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd)) { ERR(ctx, "KDSKBDIACR: %s", strerror(errno)); return -1; } } return (int) count; }