|
Packit |
ec106e |
#include "config.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include <linux/keyboard.h>
|
|
Packit |
ec106e |
#include <stdio.h>
|
|
Packit |
ec106e |
#include <string.h>
|
|
Packit |
ec106e |
#include <stdlib.h>
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include "keymap.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include "contextP.h"
|
|
Packit |
ec106e |
#include "ksyms.h"
|
|
Packit |
ec106e |
#include "nls.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include "syms.cp1250.h"
|
|
Packit |
ec106e |
#include "syms.ethiopic.h"
|
|
Packit |
ec106e |
#include "syms.iso8859_15.h"
|
|
Packit |
ec106e |
#include "syms.iso8859_5.h"
|
|
Packit |
ec106e |
#include "syms.iso8859_7.h"
|
|
Packit |
ec106e |
#include "syms.iso8859_8.h"
|
|
Packit |
ec106e |
#include "syms.iso8859_9.h"
|
|
Packit |
ec106e |
#include "syms.koi8.h"
|
|
Packit |
ec106e |
#include "syms.latin1.h"
|
|
Packit |
ec106e |
#include "syms.latin2.h"
|
|
Packit |
ec106e |
#include "syms.latin3.h"
|
|
Packit |
ec106e |
#include "syms.latin4.h"
|
|
Packit |
ec106e |
#include "syms.mazovia.h"
|
|
Packit |
ec106e |
#include "syms.sami.h"
|
|
Packit |
ec106e |
#include "syms.thai.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include "syms.synonyms.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#include "syms.ktyp.h"
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#define E(x) \
|
|
Packit |
ec106e |
{ \
|
|
Packit |
ec106e |
x, sizeof(x) / sizeof(x[0]) \
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const syms_entry syms[] = {
|
|
Packit |
ec106e |
E(iso646_syms), /* KT_LATIN */
|
|
Packit |
ec106e |
E(fn_syms), /* KT_FN */
|
|
Packit |
ec106e |
E(spec_syms), /* KT_SPEC */
|
|
Packit |
ec106e |
E(pad_syms), /* KT_PAD */
|
|
Packit |
ec106e |
E(dead_syms), /* KT_DEAD */
|
|
Packit |
ec106e |
E(cons_syms), /* KT_CONS */
|
|
Packit |
ec106e |
E(cur_syms), /* KT_CUR */
|
|
Packit |
ec106e |
E(shift_syms), /* KT_SHIFT */
|
|
Packit |
ec106e |
{ 0, 0 }, /* KT_META */
|
|
Packit |
ec106e |
E(ascii_syms), /* KT_ASCII */
|
|
Packit |
ec106e |
E(lock_syms), /* KT_LOCK */
|
|
Packit |
ec106e |
{ 0, 0 }, /* KT_LETTER */
|
|
Packit |
ec106e |
E(sticky_syms), /* KT_SLOCK */
|
|
Packit |
ec106e |
{ 0, 0 }, /* */
|
|
Packit |
ec106e |
E(brl_syms) /* KT_BRL */
|
|
Packit |
ec106e |
};
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
#undef E
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const unsigned int syms_size = sizeof(syms) / sizeof(syms_entry);
|
|
Packit |
ec106e |
const unsigned int syn_size = sizeof(synonyms) / sizeof(synonyms[0]);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const struct cs {
|
|
Packit |
ec106e |
const char *charset;
|
|
Packit |
ec106e |
const sym *charnames;
|
|
Packit |
ec106e |
const int start;
|
|
Packit |
ec106e |
} charsets[] = {
|
|
Packit |
ec106e |
{ "iso-8859-1", latin1_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-2", latin2_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-3", latin3_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-4", latin4_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-5", iso8859_5_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-7", iso8859_7_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-8", iso8859_8_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-9", iso8859_9_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-10", latin6_syms, 160 },
|
|
Packit |
ec106e |
{ "iso-8859-15", iso8859_15_syms, 160 },
|
|
Packit |
ec106e |
{ "mazovia", mazovia_syms, 128 },
|
|
Packit |
ec106e |
{ "cp-1250", cp1250_syms, 128 },
|
|
Packit |
ec106e |
{ "koi8-r", koi8_syms, 128 },
|
|
Packit |
ec106e |
{ "koi8-u", koi8_syms, 128 },
|
|
Packit |
ec106e |
{ "tis-620", tis_620_syms, 160 }, /* thai */
|
|
Packit |
ec106e |
{ "iso-10646-18", iso10646_18_syms, 159 }, /* ethiopic */
|
|
Packit |
ec106e |
{ "iso-ir-197", iso_ir_197_syms, 160 }, /* sami */
|
|
Packit |
ec106e |
{ "iso-ir-209", iso_ir_209_syms, 160 }, /* sami */
|
|
Packit |
ec106e |
};
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
static const unsigned int charsets_size = sizeof(charsets) / sizeof(charsets[0]);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* Functions for both dumpkeys and loadkeys. */
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
void lk_list_charsets(FILE *f)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
int lth, ct;
|
|
Packit |
ec106e |
unsigned int i, j;
|
|
Packit |
ec106e |
char *mm[] = { "iso-8859-", "koi8-" };
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (j = 0; j < sizeof(mm) / sizeof(mm[0]); j++) {
|
|
Packit |
ec106e |
if (j)
|
|
Packit |
ec106e |
fprintf(f, ",");
|
|
Packit |
ec106e |
fprintf(f, "%s{", mm[j]);
|
|
Packit |
ec106e |
ct = 0;
|
|
Packit |
ec106e |
lth = strlen(mm[j]);
|
|
Packit |
ec106e |
for (i = 1; i < charsets_size; i++) {
|
|
Packit |
ec106e |
if (!strncmp(charsets[i].charset, mm[j], lth)) {
|
|
Packit |
ec106e |
if (ct++)
|
|
Packit |
ec106e |
fprintf(f, ",");
|
|
Packit |
ec106e |
fprintf(f, "%s", charsets[i].charset + lth);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
fprintf(f, "}");
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
for (i = 0; i < charsets_size; i++) {
|
|
Packit |
ec106e |
for (j = 0; j < sizeof(mm) / sizeof(mm[0]); j++) {
|
|
Packit |
ec106e |
lth = strlen(mm[j]);
|
|
Packit |
ec106e |
if (!strncmp(charsets[i].charset, mm[j], lth))
|
|
Packit |
ec106e |
goto nxti;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
fprintf(f, ",%s", charsets[i].charset);
|
|
Packit |
ec106e |
nxti:;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
fprintf(f, "\n");
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const char *
|
|
Packit |
ec106e |
lk_get_charset(struct lk_ctx *ctx)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
if (!ctx || ctx->charset >= charsets_size)
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return charsets[ctx->charset].charset;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
int lk_set_charset(struct lk_ctx *ctx, const char *charset)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
unsigned int i;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < charsets_size; i++) {
|
|
Packit |
ec106e |
if (!strcasecmp(charsets[i].charset, charset)) {
|
|
Packit |
ec106e |
ctx->charset = i;
|
|
Packit |
ec106e |
return 0;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
return 1;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
unsigned int
|
|
Packit |
ec106e |
get_sym_size(struct lk_ctx *ctx, unsigned int ktype)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
if (ktype >= syms_size) {
|
|
Packit |
ec106e |
ERR(ctx, _("unable to get symbol by wrong type: %d"), ktype);
|
|
Packit |
ec106e |
return 0;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return syms[ktype].size;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const char *
|
|
Packit |
ec106e |
get_sym(struct lk_ctx *ctx, unsigned int ktype, unsigned int index)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
if (!get_sym_size(ctx, ktype))
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (index >= syms[ktype].size) {
|
|
Packit |
ec106e |
ERR(ctx, _("unable to get symbol of %d type by wrong index: %d"), ktype, index);
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return syms[ktype].table[index];
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
char *
|
|
Packit |
ec106e |
lk_get_sym(struct lk_ctx *ctx, unsigned int ktype, unsigned int index)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
const char *ksym = get_sym(ctx, ktype, index);
|
|
Packit |
ec106e |
return (ksym ? strdup(ksym) : NULL);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
const char *
|
|
Packit |
ec106e |
codetoksym(struct lk_ctx *ctx, int code)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
unsigned int i;
|
|
Packit |
ec106e |
int j;
|
|
Packit |
ec106e |
sym *p;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (code < 0)
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (code < 0x1000) { /* "traditional" keysym */
|
|
Packit |
ec106e |
if (code < 0x80)
|
|
Packit |
ec106e |
return get_sym(ctx, KT_LATIN, code);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (KTYP(code) == KT_META)
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (KTYP(code) == KT_LETTER)
|
|
Packit |
ec106e |
code = K(KT_LATIN, KVAL(code));
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (KTYP(code) > KT_LATIN)
|
|
Packit |
ec106e |
return get_sym(ctx, KTYP(code), KVAL(code));
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
i = ctx->charset;
|
|
Packit |
ec106e |
p = (sym *)charsets[i].charnames;
|
|
Packit |
ec106e |
if (p && (KVAL(code) >= charsets[i].start)) {
|
|
Packit |
ec106e |
p += KVAL(code) - charsets[i].start;
|
|
Packit |
ec106e |
if (p->name[0])
|
|
Packit |
ec106e |
return p->name;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
else { /* Unicode keysym */
|
|
Packit |
ec106e |
code ^= 0xf000;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (code < 0x80)
|
|
Packit |
ec106e |
return get_sym(ctx, KT_LATIN, code);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < charsets_size; i++) {
|
|
Packit |
ec106e |
p = (sym *)charsets[i].charnames;
|
|
Packit |
ec106e |
if (p) {
|
|
Packit |
ec106e |
for (j = charsets[i].start; j < 256; j++, p++) {
|
|
Packit |
ec106e |
if (p->uni == code && p->name[0])
|
|
Packit |
ec106e |
return p->name;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
char *
|
|
Packit |
ec106e |
lk_code_to_ksym(struct lk_ctx *ctx, int code)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
const char *s;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
s = codetoksym(ctx, code);
|
|
Packit |
ec106e |
if (!s)
|
|
Packit |
ec106e |
return NULL;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return strdup(s);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* Functions for loadkeys. */
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
static int
|
|
Packit |
ec106e |
kt_latin(struct lk_ctx *ctx, const char *s, int direction)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
unsigned int i, max;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
sym *p = (sym *)charsets[ctx->charset].charnames;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
max = (direction == TO_UNICODE ? 128 : 256); // TODO(dmage): is 256 valid for ethiopic charset?
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = charsets[ctx->charset].start; i < max; i++, p++) {
|
|
Packit |
ec106e |
if (p->name[0] && !strcmp(s, p->name))
|
|
Packit |
ec106e |
return K(KT_LATIN, i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
max = (direction == TO_UNICODE ? 128 : syms[KT_LATIN].size);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < max; i++) {
|
|
Packit |
ec106e |
if (!strcmp(s, get_sym(ctx, KT_LATIN, i)))
|
|
Packit |
ec106e |
return K(KT_LATIN, i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return -1;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
int ksymtocode(struct lk_ctx *ctx, const char *s, int direction)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
unsigned int i, j;
|
|
Packit |
ec106e |
int n;
|
|
Packit |
ec106e |
int keycode;
|
|
Packit |
ec106e |
sym *p;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (direction == TO_AUTO)
|
|
Packit |
ec106e |
direction = (ctx->flags & LK_FLAG_PREFER_UNICODE)
|
|
Packit |
ec106e |
? TO_UNICODE
|
|
Packit |
ec106e |
: TO_8BIT;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (!strncmp(s, "Meta_", 5)) {
|
|
Packit |
ec106e |
keycode = ksymtocode(ctx, s + 5, TO_8BIT);
|
|
Packit |
ec106e |
if (KTYP(keycode) == KT_LATIN)
|
|
Packit |
ec106e |
return K(KT_META, KVAL(keycode));
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* Avoid error messages for Meta_acute with UTF-8 */
|
|
Packit |
ec106e |
else if (direction == TO_UNICODE)
|
|
Packit |
ec106e |
return (0);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* fall through to error printf */
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if ((n = kt_latin(ctx, s, direction)) >= 0) {
|
|
Packit |
ec106e |
return n;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 1; i < syms_size; i++) {
|
|
Packit |
ec106e |
for (j = 0; j < syms[i].size; j++) {
|
|
Packit |
ec106e |
if (!strcmp(s, get_sym(ctx, i, j)))
|
|
Packit |
ec106e |
return K(i, j);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < syn_size; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, synonyms[i].synonym))
|
|
Packit |
ec106e |
return ksymtocode(ctx, synonyms[i].official_name, direction);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (direction == TO_UNICODE) {
|
|
Packit |
ec106e |
i = ctx->charset;
|
|
Packit |
ec106e |
p = (sym *)charsets[i].charnames;
|
|
Packit |
ec106e |
if (p) {
|
|
Packit |
ec106e |
for (j = charsets[i].start; j < 256; j++, p++) {
|
|
Packit |
ec106e |
if (!strcmp(s, p->name))
|
|
Packit |
ec106e |
return (p->uni ^ 0xf000);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* not found in the current charset, maybe we'll have good luck in others? */
|
|
Packit |
ec106e |
for (i = 0; i < charsets_size; i++) {
|
|
Packit |
ec106e |
if (i == ctx->charset) {
|
|
Packit |
ec106e |
continue;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
p = (sym *)charsets[i].charnames;
|
|
Packit |
ec106e |
if (p) {
|
|
Packit |
ec106e |
for (j = charsets[i].start; j < 256; j++, p++) {
|
|
Packit |
ec106e |
if (!strcmp(s, p->name))
|
|
Packit |
ec106e |
return (p->uni ^ 0xf000);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
} else /* if (!chosen_charset[0]) */ {
|
|
Packit |
ec106e |
/* note: some keymaps use latin1 but with euro,
|
|
Packit |
ec106e |
so set_charset() would fail */
|
|
Packit |
ec106e |
/* note: some keymaps with charset line still use
|
|
Packit |
ec106e |
symbols from more than one character set,
|
|
Packit |
ec106e |
so we cannot have the `if (!chosen_charset[0])' here */
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < 256 - 160; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, latin1_syms[i].name)) {
|
|
Packit |
ec106e |
INFO(ctx, _("assuming iso-8859-1 %s"), s);
|
|
Packit |
ec106e |
return K(KT_LATIN, 160 + i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < 256 - 160; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, iso8859_15_syms[i].name)) {
|
|
Packit |
ec106e |
INFO(ctx, _("assuming iso-8859-15 %s"), s);
|
|
Packit |
ec106e |
return K(KT_LATIN, 160 + i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < 256 - 160; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, latin2_syms[i].name)) {
|
|
Packit |
ec106e |
INFO(ctx, _("assuming iso-8859-2 %s"), s);
|
|
Packit |
ec106e |
return K(KT_LATIN, 160 + i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < 256 - 160; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, latin3_syms[i].name)) {
|
|
Packit |
ec106e |
INFO(ctx, _("assuming iso-8859-3 %s"), s);
|
|
Packit |
ec106e |
return K(KT_LATIN, 160 + i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
for (i = 0; i < 256 - 160; i++)
|
|
Packit |
ec106e |
if (!strcmp(s, latin4_syms[i].name)) {
|
|
Packit |
ec106e |
INFO(ctx, _("assuming iso-8859-4 %s"), s);
|
|
Packit |
ec106e |
return K(KT_LATIN, 160 + i);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
ERR(ctx, _("unknown keysym '%s'\n"), s);
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
return CODE_FOR_UNKNOWN_KSYM;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
int lk_ksym_to_unicode(struct lk_ctx *ctx, const char *s)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
return ksymtocode(ctx, s, TO_UNICODE);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
int convert_code(struct lk_ctx *ctx, int code, int direction)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
const char *ksym;
|
|
Packit |
ec106e |
int unicode_forced = (direction == TO_UNICODE);
|
|
Packit |
ec106e |
int input_is_unicode = (code >= 0x1000);
|
|
Packit |
ec106e |
int result;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (direction == TO_AUTO)
|
|
Packit |
ec106e |
direction = (ctx->flags & LK_FLAG_PREFER_UNICODE)
|
|
Packit |
ec106e |
? TO_UNICODE
|
|
Packit |
ec106e |
: TO_8BIT;
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
if (KTYP(code) == KT_META)
|
|
Packit |
ec106e |
return code;
|
|
Packit |
ec106e |
else if (!input_is_unicode && code < 0x80)
|
|
Packit |
ec106e |
/* basic ASCII is fine in every situation */
|
|
Packit |
ec106e |
return code;
|
|
Packit |
ec106e |
else if (input_is_unicode && (code ^ 0xf000) < 0x80)
|
|
Packit |
ec106e |
/* so is Unicode "Basic Latin" */
|
|
Packit |
ec106e |
return code ^ 0xf000;
|
|
Packit |
ec106e |
else if ((input_is_unicode && direction == TO_UNICODE) ||
|
|
Packit |
ec106e |
(!input_is_unicode && direction == TO_8BIT))
|
|
Packit |
ec106e |
/* no conversion necessary */
|
|
Packit |
ec106e |
result = code;
|
|
Packit |
ec106e |
else {
|
|
Packit |
ec106e |
/* depending on direction, this will give us either an 8-bit
|
|
Packit |
ec106e |
* K(KTYP, KVAL) or a Unicode keysym xor 0xf000 */
|
|
Packit |
ec106e |
ksym = codetoksym(ctx, code);
|
|
Packit |
ec106e |
if (ksym)
|
|
Packit |
ec106e |
result = ksymtocode(ctx, ksym, direction);
|
|
Packit |
ec106e |
else
|
|
Packit |
ec106e |
result = code;
|
|
Packit |
ec106e |
if (direction == TO_UNICODE && KTYP(code) == KT_LETTER && (result ^ 0xf000) < 0x100) {
|
|
Packit |
ec106e |
/* Unicode Latin-1 Supplement */
|
|
Packit |
ec106e |
result = K(KT_LETTER, result ^ 0xf000);
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
/* if direction was TO_UNICODE from the beginning, we return the true
|
|
Packit |
ec106e |
* Unicode value (without the 0xf000 mask) */
|
|
Packit |
ec106e |
if (unicode_forced && result >= 0x1000)
|
|
Packit |
ec106e |
return result ^ 0xf000;
|
|
Packit |
ec106e |
else
|
|
Packit |
ec106e |
return result;
|
|
Packit |
ec106e |
}
|
|
Packit |
ec106e |
|
|
Packit |
ec106e |
int add_capslock(struct lk_ctx *ctx, int code)
|
|
Packit |
ec106e |
{
|
|
Packit |
ec106e |
if (KTYP(code) == KT_LATIN && (!(ctx->flags & LK_FLAG_PREFER_UNICODE) || code < 0x80))
|
|
Packit |
ec106e |
return K(KT_LETTER, KVAL(code));
|
|
Packit |
ec106e |
else if ((code ^ 0xf000) < 0x100)
|
|
Packit |
ec106e |
/* Unicode Latin-1 Supplement */
|
|
Packit |
ec106e |
/* a bit dirty to use KT_LETTER here, but it should work */
|
|
Packit |
ec106e |
return K(KT_LETTER, code ^ 0xf000);
|
|
Packit |
ec106e |
else
|
|
Packit |
ec106e |
return convert_code(ctx, code, TO_AUTO);
|
|
Packit |
ec106e |
}
|