From 90c865535e86af373945fda853b54fd91c168f8a Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 12 Dec 2023 17:13:12 +0100 Subject: [PATCH] Move dead/combining keys to separate table This is a manually set up table specific for TigerVNC. For clarity, separate it out from the general keysym/Unicode table. --- vncviewer/keysym2ucs.c | 121 ++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 39 deletions(-) diff --git a/vncviewer/keysym2ucs.c b/vncviewer/keysym2ucs.c index 33a5653d..5d044fa5 100644 --- a/vncviewer/keysym2ucs.c +++ b/vncviewer/keysym2ucs.c @@ -819,23 +819,26 @@ static const struct codepair keysymtab[] = { { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ - { 0xfe50, 0x0300 }, /* COMBINING GRAVE ACCENT */ - { 0xfe51, 0x0301 }, /* COMBINING ACUTE ACCENT */ - { 0xfe52, 0x0302 }, /* COMBINING CIRCUMFLEX ACCENT */ - { 0xfe53, 0x0303 }, /* COMBINING TILDE */ - { 0xfe54, 0x0304 }, /* COMBINING MACRON */ - { 0xfe55, 0x0306 }, /* COMBINING BREVE */ - { 0xfe56, 0x0307 }, /* COMBINING DOT ABOVE */ - { 0xfe57, 0x0308 }, /* COMBINING DIAERESIS */ - { 0xfe58, 0x030a }, /* COMBINING RING ABOVE */ - { 0xfe59, 0x030b }, /* COMBINING DOUBLE ACUTE ACCENT */ - { 0xfe5a, 0x030c }, /* COMBINING CARON */ - { 0xfe5b, 0x0327 }, /* COMBINING CEDILLA */ - { 0xfe5c, 0x0328 }, /* COMBINING OGONEK */ - { 0xfe5d, 0x0345 }, /* COMBINING GREEK YPOGEGRAMMENI */ - { 0xfe5e, 0x3099 }, /* COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0xfe5f, 0x309a }, /* COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0xfe60, 0x0323 }, /* COMBINING DOT BELOW */ +}; + +static const struct codepair deadtab[] = { + { 0xfe50, 0x0300 }, /* dead_grave ` COMBINING GRAVE ACCENT */ + { 0xfe51, 0x0301 }, /* dead_acute ´ COMBINING ACUTE ACCENT */ + { 0xfe52, 0x0302 }, /* dead_circumflex ^ COMBINING CIRCUMFLEX ACCENT */ + { 0xfe53, 0x0303 }, /* dead_tilde ~ COMBINING TILDE */ + { 0xfe54, 0x0304 }, /* dead_macron ¯ COMBINING MACRON */ + { 0xfe55, 0x0306 }, /* dead_breve ˘ COMBINING BREVE */ + { 0xfe56, 0x0307 }, /* dead_abovedot ˙ COMBINING DOT ABOVE */ + { 0xfe57, 0x0308 }, /* dead_diaeresis ¨ COMBINING DIAERESIS */ + { 0xfe58, 0x030a }, /* dead_abovering ˚ COMBINING RING ABOVE */ + { 0xfe59, 0x030b }, /* dead_doubleacute ˝ COMBINING DOUBLE ACUTE ACCENT */ + { 0xfe5a, 0x030c }, /* dead_caron ˇ COMBINING CARON */ + { 0xfe5b, 0x0327 }, /* dead_cedilla ¸ COMBINING CEDILLA */ + { 0xfe5c, 0x0328 }, /* dead_ogonek ¸ COMBINING OGONEK */ + { 0xfe5d, 0x0345 }, /* dead_iota ͺ COMBINING GREEK YPOGEGRAMMENI */ + { 0xfe5e, 0x3099 }, /* dead_voiced_sound ゛ COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0xfe5f, 0x309a }, /* dead_semivoiced_sound ゜ COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0xfe60, 0x0323 }, /* dead_belowdot . COMBINING DOT BELOW */ }; static const struct combiningpair combinetab[] = { @@ -863,54 +866,94 @@ static const struct combiningpair combinetab[] = { { 0x0385, 0x0344 }, /* GREEK DIALYTIKA TONOS ΅ COMBINING GREEK DIALYTIKA TONOS */ }; -unsigned keysym2ucs(unsigned keysym) +static unsigned find_ucs(unsigned keysym, + const struct codepair *table, int entries) { int min = 0; - int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + int max = entries - 1; int mid; - /* first check for Latin-1 characters (1:1 mapping) */ - if ((keysym >= 0x0020 && keysym <= 0x007e) || - (keysym >= 0x00a0 && keysym <= 0x00ff)) - return keysym; - - /* also check for directly encoded 24-bit UCS characters */ - if ((keysym & 0xff000000) == 0x01000000) - return keysym & 0x00ffffff; - /* binary search in table */ while (max >= min) { mid = (min + max) / 2; - if (keysymtab[mid].keysym < keysym) + if (table[mid].keysym < keysym) min = mid + 1; - else if (keysymtab[mid].keysym > keysym) + else if (table[mid].keysym > keysym) max = mid - 1; else { /* found it */ - return keysymtab[mid].ucs; + return table[mid].ucs; } } + return -1; +} + +static unsigned find_sym(unsigned ucs, + const struct codepair *table, int entries) +{ + int cur = 0; + int max = entries - 1; + + /* linear search in table */ + while (cur <= max) { + if (table[cur].ucs == ucs) + return table[cur].keysym; + cur++; + } + + return NoSymbol; +} + +unsigned keysym2ucs(unsigned keysym) +{ + unsigned ucs; + + /* first check for Latin-1 characters (1:1 mapping) */ + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + return keysym; + + /* also check for directly encoded 24-bit UCS characters */ + if ((keysym & 0xff000000) == 0x01000000) + return keysym & 0x00ffffff; + + /* normal key? */ + ucs = find_ucs(keysym, keysymtab, + sizeof(keysymtab) / sizeof(struct codepair)); + if (ucs != (unsigned)-1) + return ucs; + + /* dead key? */ + ucs = find_ucs(keysym, deadtab, + sizeof(deadtab) / sizeof(struct codepair)); + if (ucs != (unsigned)-1) + return ucs; + /* no matching Unicode value found */ return -1; } unsigned ucs2keysym(unsigned ucs) { - int cur = 0; - int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + unsigned keysym; /* first check for Latin-1 characters (1:1 mapping) */ if ((ucs >= 0x0020 && ucs <= 0x007e) || (ucs >= 0x00a0 && ucs <= 0x00ff)) return ucs; - /* linear search in table */ - while (cur <= max) { - if (keysymtab[cur].ucs == ucs) - return keysymtab[cur].keysym; - cur++; - } + /* normal key? */ + keysym = find_sym(ucs, keysymtab, + sizeof(keysymtab) / sizeof(struct codepair)); + if (keysym != NoSymbol) + return keysym; + + /* dead key? */ + keysym = find_sym(ucs, deadtab, + sizeof(deadtab) / sizeof(struct codepair)); + if (keysym != NoSymbol) + return keysym; /* us the directly encoded 24-bit UCS character */ if ((ucs & 0xff000000) == 0) -- 2.39.5