[vlc-devel] commit: Support any Unicode symbol as part of an hotkey ( Rémi Denis-Courmont )

git version control git at videolan.org
Wed Oct 7 21:43:36 CEST 2009


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Oct  7 22:39:59 2009 +0300| [9b12eb8cd33061e05fe870391d965a66080a7dfe] | committer: Rémi Denis-Courmont 

Support any Unicode symbol as part of an hotkey

Currently, only the core supports this correctly, however.

Note that this means key configuration values become case sensitive
(case insentivity would be too complicated), but this should not be
a problem so long as the core key<->string functions are always used.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9b12eb8cd33061e05fe870391d965a66080a7dfe
---

 src/config/keys.c |  145 ++++++++++++++++++++++++++++------------------------
 1 files changed, 78 insertions(+), 67 deletions(-)

diff --git a/src/config/keys.c b/src/config/keys.c
index ef251af..d7687c4 100644
--- a/src/config/keys.c
+++ b/src/config/keys.c
@@ -54,70 +54,6 @@ static const struct key_descriptor_s vlc_keys[] =
 {
     { "Unset", KEY_UNSET },
     { "Space", ' ' },
-    { "!", '!' },
-    { "\"", '\"' },
-    { "#", '#' },
-    { "$", '$' },
-    { "%", '%' },
-    { "&", '&' },
-    { "'", '\'' },
-    { "(", ')' },
-    { ")", ')' },
-    { "*", '*' },
-    { "+", '+' },
-    { ",", ',' },
-    { "-", '-' },
-    { ".", '.' },
-    { "/", '/' },
-    { "0", '0' },
-    { "1", '1' },
-    { "2", '2' },
-    { "3", '3' },
-    { "4", '4' },
-    { "5", '5' },
-    { "6", '6' },
-    { "7", '7' },
-    { "8", '8' },
-    { "9", '9' },
-    { ":", ':' },
-    { ";", ';' },
-    { "<", '<' },
-    { "=", '=' },
-    { ">", '>' },
-    { "?", '?' },
-    { "@", '@' },
-    { "[", '[' },
-    { "\\", '\\' },
-    { "]", ']' },
-    { "^", '^' },
-    { "_", '_' },
-    { "`", '`' },
-    { "a", 'a' },
-    { "b", 'b' },
-    { "c", 'c' },
-    { "d", 'd' },
-    { "e", 'e' },
-    { "f", 'f' },
-    { "g", 'g' },
-    { "h", 'h' },
-    { "i", 'i' },
-    { "j", 'j' },
-    { "k", 'k' },
-    { "l", 'l' },
-    { "m", 'm' },
-    { "n", 'n' },
-    { "o", 'o' },
-    { "p", 'p' },
-    { "q", 'q' },
-    { "r", 'r' },
-    { "s", 's' },
-    { "t", 't' },
-    { "u", 'u' },
-    { "v", 'v' },
-    { "w", 'w' },
-    { "x", 'x' },
-    { "y", 'y' },
-    { "z", 'z' },
     { "Left", KEY_LEFT },
     { "Right", KEY_RIGHT },
     { "Up", KEY_UP },
@@ -171,13 +107,85 @@ static int cmpkey (const void *key, const void *elem)
     return ((uintptr_t)key) - ((key_descriptor_t *)elem)->i_key_code;
 }
 
+/* Convert Unicode code point to UTF-8 */
+static char *utf8_cp (uint_fast32_t cp, char *buf)
+{
+    if (cp < (1 << 7))
+    {
+        buf[1] = 0;
+        buf[0] = cp;
+    }
+    else if (cp < (1 << 11))
+    {
+        buf[2] = 0;
+        buf[1] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[0] = 0xC0 | cp;
+    }
+    else if (cp < (1 << 16))
+    {
+        buf[3] = 0;
+        buf[2] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[1] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[0] = 0xE0 | cp;
+    }
+    else if (cp < (1 << 21))
+    {
+        buf[4] = 0;
+        buf[3] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[2] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[1] = 0x80 | (cp & 0x3F);
+        cp >>= 6;
+        buf[0] = 0xE0 | cp;
+    }
+    else
+        return NULL;
+    return buf;
+}
+
+/* Convert UTF-8 to Unicode code point */
+static uint_fast32_t cp_utf8 (const char *utf8)
+{
+    uint8_t f = utf8[0];
+    size_t l = strlen (utf8);
+
+    if (f < 0x80) /* ASCII (7 bits) */
+        return f;
+    if (f < 0xC0 || l < 2) /* bad */
+        return 0;
+    if (f < 0xE0) /* two bytes (11 bits) */
+        return ((f & 0x1F) << 6) | (utf8[1] & 0x3F);
+    if (l < 3) /* bad */
+        return 0;
+    if (f < 0xF0) /* three bytes (16 bits) */
+        return ((f & 0x0F) << 12) | ((utf8[1] & 0x3F) << 6)
+               | (utf8[2] & 0x3F);
+    if (l < 4)
+        return 0;
+    if (f < 0xF8) /* four bytes (21 bits) */
+        return ((f & 0x07) << 18) | ((utf8[1] & 0x3F) << 12)
+               | ((utf8[2] & 0x3F) << 6) | (utf8[3] & 0x3F);
+    return 0;
+}
+
 char *KeyToString (uint_fast32_t sym)
 {
     key_descriptor_t *d;
 
     d = bsearch ((void *)(uintptr_t)sym, vlc_keys, vlc_num_keys,
                  sizeof (vlc_keys[0]), cmpkey);
-    return d ? strdup (d->psz_key_string) : NULL;
+    if (d)
+        return strdup (d->psz_key_string);
+
+    char buf[5];
+    if (utf8_cp (sym, buf))
+        return strdup (buf);
+
+    return NULL;
 }
 
 uint_fast32_t StringToKey (char *name)
@@ -186,7 +194,7 @@ uint_fast32_t StringToKey (char *name)
         if (!strcmp (vlc_keys[i].psz_key_string, name))
             return vlc_keys[i].i_key_code;
 
-    return 0;
+    return cp_utf8 (name);
 }
 
 uint_fast32_t ConfigStringToKey (const char *name)
@@ -215,7 +223,7 @@ uint_fast32_t ConfigStringToKey (const char *name)
         if (!strcasecmp( vlc_keys[i].psz_key_string, name))
             return vlc_keys[i].i_key_code | mods;
 
-    return 0;
+    return cp_utf8 (name) | mods;
 }
 
 char *ConfigKeyToString (uint_fast32_t i_key)
@@ -239,12 +247,15 @@ char *ConfigKeyToString (uint_fast32_t i_key)
     }
 
     key_descriptor_t *d;
+    char buf[5];
 
     i_key &= ~KEY_MODIFIER;
     d = bsearch ((void *)(uintptr_t)i_key, vlc_keys, vlc_num_keys,
                  sizeof (vlc_keys[0]), cmpkey);
     if (d)
         p += snprintf (p, psz_end - p, "%s", d->psz_key_string);
+    else if (utf8_cp (i_key, buf))
+        p += snprintf (p, psz_end - p, "%s", buf);
     else
         return NULL;
 




More information about the vlc-devel mailing list