]> git.sesse.net Git - vlc/blobdiff - src/config/keys.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / src / config / keys.c
index 07980e682d01751c41863aee71446b4b9020e0d5..637d4b1445f83eff1b9ebfe0c5ca657c42ecfb15 100644 (file)
@@ -53,76 +53,15 @@ enum { vlc_num_modifiers=sizeof(vlc_modifiers)
 static const struct key_descriptor_s vlc_keys[] =
 {
     { "Unset", KEY_UNSET },
+    { "Backspace", KEY_BACKSPACE },
+    { "Tab", KEY_TAB },
+    { "Enter", KEY_ENTER },
+    { "Esc", KEY_ESC },
     { "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 },
     { "Down", KEY_DOWN },
-    { "Enter", KEY_ENTER },
     { "F1", KEY_F1 },
     { "F2", KEY_F2 },
     { "F3", KEY_F3 },
@@ -140,11 +79,8 @@ static const struct key_descriptor_s vlc_keys[] =
     { "Insert", KEY_INSERT },
     { "Delete", KEY_DELETE },
     { "Menu", KEY_MENU },
-    { "Esc", KEY_ESC },
     { "Page Up", KEY_PAGEUP },
     { "Page Down", KEY_PAGEDOWN },
-    { "Tab", KEY_TAB },
-    { "Backspace", KEY_BACKSPACE },
     { "Browser Back", KEY_BROWSER_BACK },
     { "Browser Forward", KEY_BROWSER_FORWARD },
     { "Browser Refresh", KEY_BROWSER_REFRESH },
@@ -171,14 +107,85 @@ static int cmpkey (const void *key, const void *elem)
     return ((uintptr_t)key) - ((key_descriptor_t *)elem)->i_key_code;
 }
 
-const char *KeyToString (uint_fast32_t sym)
+/* 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 = (key_descriptor_t *)
-        bsearch ((void *)(uintptr_t)sym, vlc_keys, vlc_num_keys,
+    d = bsearch ((void *)(uintptr_t)sym, vlc_keys, vlc_num_keys,
                  sizeof (vlc_keys[0]), cmpkey);
-    return d ? 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)
@@ -187,17 +194,16 @@ 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)
 {
     uint_fast32_t mods = 0;
 
-    const char *psz_parser = name;
     for (;;)
     {
-        psz_parser = strchr (psz_parser, '-');
+        const char *psz_parser = strchr (name, '-');
         if (psz_parser == NULL || psz_parser == name)
             break;
 
@@ -216,7 +222,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)
@@ -238,14 +244,19 @@ char *ConfigKeyToString (uint_fast32_t i_key)
                            vlc_modifiers[i].psz_key_string);
         }
     }
-    for (size_t i = 0; i < vlc_num_keys; i++)
-    {
-        if ((i_key & ~KEY_MODIFIER) == vlc_keys[i].i_key_code)
-        {
-            p += snprintf (p, psz_end - p, "%s",
-                           vlc_keys[i].psz_key_string);
-            break;
-        }
-    }
+
+    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;
+
     return psz_key;
 }