1 /*****************************************************************************
2 * keys.c: keys configuration
3 *****************************************************************************
4 * Copyright (C) 2003-2009 the VideoLAN team
6 * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
29 * This file defines functions and structures for hotkey handling in vlc
32 #include <vlc_common.h>
34 #include "configuration.h"
37 typedef struct key_descriptor_s
39 const char *psz_key_string;
43 static const struct key_descriptor_s vlc_modifiers[] =
45 { "Alt", KEY_MODIFIER_ALT },
46 { "Shift", KEY_MODIFIER_SHIFT },
47 { "Ctrl", KEY_MODIFIER_CTRL },
48 { "Meta", KEY_MODIFIER_META },
49 { "Command", KEY_MODIFIER_COMMAND }
51 enum { vlc_num_modifiers=sizeof(vlc_modifiers)
52 /sizeof(struct key_descriptor_s) };
54 static const struct key_descriptor_s vlc_keys[] =
56 { "Unset", KEY_UNSET },
57 { "Backspace", KEY_BACKSPACE },
59 { "Enter", KEY_ENTER },
63 { "Right", KEY_RIGHT },
80 { "Insert", KEY_INSERT },
81 { "Delete", KEY_DELETE },
83 { "Page Up", KEY_PAGEUP },
84 { "Page Down", KEY_PAGEDOWN },
85 { "Browser Back", KEY_BROWSER_BACK },
86 { "Browser Forward", KEY_BROWSER_FORWARD },
87 { "Browser Refresh", KEY_BROWSER_REFRESH },
88 { "Browser Stop", KEY_BROWSER_STOP },
89 { "Browser Search", KEY_BROWSER_SEARCH },
90 { "Browser Favorites", KEY_BROWSER_FAVORITES },
91 { "Browser Home", KEY_BROWSER_HOME },
92 { "Volume Mute", KEY_VOLUME_MUTE },
93 { "Volume Down", KEY_VOLUME_DOWN },
94 { "Volume Up", KEY_VOLUME_UP },
95 { "Media Next Track", KEY_MEDIA_NEXT_TRACK },
96 { "Media Prev Track", KEY_MEDIA_PREV_TRACK },
97 { "Media Stop", KEY_MEDIA_STOP },
98 { "Media Play Pause", KEY_MEDIA_PLAY_PAUSE },
99 { "Mouse Wheel Up", KEY_MOUSEWHEELUP },
100 { "Mouse Wheel Down", KEY_MOUSEWHEELDOWN },
101 { "Mouse Wheel Left", KEY_MOUSEWHEELLEFT },
102 { "Mouse Wheel Right", KEY_MOUSEWHEELRIGHT },
104 enum { vlc_num_keys=sizeof(vlc_keys)/sizeof(struct key_descriptor_s) };
106 static int cmpkey (const void *key, const void *elem)
108 return ((uintptr_t)key) - ((key_descriptor_t *)elem)->i_key_code;
111 /* Convert Unicode code point to UTF-8 */
112 static char *utf8_cp (uint_fast32_t cp, char *buf)
119 else if (cp < (1 << 11))
122 buf[1] = 0x80 | (cp & 0x3F);
126 else if (cp < (1 << 16))
129 buf[2] = 0x80 | (cp & 0x3F);
131 buf[1] = 0x80 | (cp & 0x3F);
135 else if (cp < (1 << 21))
138 buf[3] = 0x80 | (cp & 0x3F);
140 buf[2] = 0x80 | (cp & 0x3F);
142 buf[1] = 0x80 | (cp & 0x3F);
151 char *KeyToString (uint_fast32_t sym)
155 d = bsearch ((void *)(uintptr_t)sym, vlc_keys, vlc_num_keys,
156 sizeof (vlc_keys[0]), cmpkey);
158 return strdup (d->psz_key_string);
161 if (utf8_cp (sym, buf))
167 uint_fast32_t ConfigStringToKey (const char *name)
169 uint_fast32_t mods = 0;
174 const char *psz_parser = strchr (name, '-');
175 if (psz_parser == NULL || psz_parser == name)
178 for (size_t i = 0; i < vlc_num_modifiers; i++)
180 if (!strncasecmp (vlc_modifiers[i].psz_key_string, name,
181 strlen (vlc_modifiers[i].psz_key_string)))
183 mods |= vlc_modifiers[i].i_key_code;
186 name = psz_parser + 1;
189 for (size_t i = 0; i < vlc_num_keys; i++)
190 if (!strcasecmp( vlc_keys[i].psz_key_string, name))
191 return vlc_keys[i].i_key_code | mods;
193 return (vlc_towc (name, &cp) > 0) ? (mods | cp) : 0;
196 char *ConfigKeyToString (uint_fast32_t i_key)
198 // Worst case appears to be 45 characters:
199 // "Command-Meta-Ctrl-Shift-Alt-Browser Favorites"
200 char *psz_key = malloc (64);
204 char *p = psz_key, *psz_end = psz_key + 54;
207 for (size_t i = 0; i < vlc_num_modifiers; i++)
209 if (i_key & vlc_modifiers[i].i_key_code)
211 p += snprintf (p, psz_end - p, "%s-",
212 vlc_modifiers[i].psz_key_string);
219 i_key &= ~KEY_MODIFIER;
220 d = bsearch ((void *)(uintptr_t)i_key, vlc_keys, vlc_num_keys,
221 sizeof (vlc_keys[0]), cmpkey);
223 p += snprintf (p, psz_end - p, "%s", d->psz_key_string);
224 else if (utf8_cp (i_key, buf))
225 p += snprintf (p, psz_end - p, "%s", buf);