]> git.sesse.net Git - vlc/blob - src/config/keys.c
Gather key functions and tables in a single file
[vlc] / src / config / keys.c
1 /*****************************************************************************
2  * keys.c: keys configuration
3  *****************************************************************************
4  * Copyright (C) 2003-2009 the VideoLAN team
5  *
6  * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 /**
28  * \file
29  * This file defines functions and structures for hotkey handling in vlc
30  */
31
32 #include <vlc_common.h>
33 #include <vlc_keys.h>
34 #include "configuration.h"
35
36 typedef struct key_descriptor_s
37 {
38     const char *psz_key_string;
39     uint32_t i_key_code;
40 } key_descriptor_t;
41
42 static const struct key_descriptor_s vlc_modifiers[] =
43 {
44     { "Alt", KEY_MODIFIER_ALT },
45     { "Shift", KEY_MODIFIER_SHIFT },
46     { "Ctrl", KEY_MODIFIER_CTRL },
47     { "Meta", KEY_MODIFIER_META },
48     { "Command", KEY_MODIFIER_COMMAND }
49 };
50 enum { vlc_num_modifiers=sizeof(vlc_modifiers)
51                         /sizeof(struct key_descriptor_s) };
52
53 static const struct key_descriptor_s vlc_keys[] =
54 {
55     { "Unset", KEY_UNSET },
56     { "Space", ' ' },
57     { "!", '!' },
58     { "\"", '\"' },
59     { "#", '#' },
60     { "$", '$' },
61     { "%", '%' },
62     { "&", '&' },
63     { "'", '\'' },
64     { "(", ')' },
65     { ")", ')' },
66     { "*", '*' },
67     { "+", '+' },
68     { ",", ',' },
69     { "-", '-' },
70     { ".", '.' },
71     { "/", '/' },
72     { "0", '0' },
73     { "1", '1' },
74     { "2", '2' },
75     { "3", '3' },
76     { "4", '4' },
77     { "5", '5' },
78     { "6", '6' },
79     { "7", '7' },
80     { "8", '8' },
81     { "9", '9' },
82     { ":", ':' },
83     { ";", ';' },
84     { "<", '<' },
85     { "=", '=' },
86     { ">", '>' },
87     { "?", '?' },
88     { "@", '@' },
89     { "[", '[' },
90     { "\\", '\\' },
91     { "]", ']' },
92     { "^", '^' },
93     { "_", '_' },
94     { "`", '`' },
95     { "a", 'a' },
96     { "b", 'b' },
97     { "c", 'c' },
98     { "d", 'd' },
99     { "e", 'e' },
100     { "f", 'f' },
101     { "g", 'g' },
102     { "h", 'h' },
103     { "i", 'i' },
104     { "j", 'j' },
105     { "k", 'k' },
106     { "l", 'l' },
107     { "m", 'm' },
108     { "n", 'n' },
109     { "o", 'o' },
110     { "p", 'p' },
111     { "q", 'q' },
112     { "r", 'r' },
113     { "s", 's' },
114     { "t", 't' },
115     { "u", 'u' },
116     { "v", 'v' },
117     { "w", 'w' },
118     { "x", 'x' },
119     { "y", 'y' },
120     { "z", 'z' },
121     { "Left", KEY_LEFT },
122     { "Right", KEY_RIGHT },
123     { "Up", KEY_UP },
124     { "Down", KEY_DOWN },
125     { "Enter", KEY_ENTER },
126     { "F1", KEY_F1 },
127     { "F2", KEY_F2 },
128     { "F3", KEY_F3 },
129     { "F4", KEY_F4 },
130     { "F5", KEY_F5 },
131     { "F6", KEY_F6 },
132     { "F7", KEY_F7 },
133     { "F8", KEY_F8 },
134     { "F9", KEY_F9 },
135     { "F10", KEY_F10 },
136     { "F11", KEY_F11 },
137     { "F12", KEY_F12 },
138     { "Home", KEY_HOME },
139     { "End", KEY_END },
140     { "Insert", KEY_INSERT },
141     { "Delete", KEY_DELETE },
142     { "Menu", KEY_MENU },
143     { "Esc", KEY_ESC },
144     { "Page Up", KEY_PAGEUP },
145     { "Page Down", KEY_PAGEDOWN },
146     { "Tab", KEY_TAB },
147     { "Backspace", KEY_BACKSPACE },
148     { "Browser Back", KEY_BROWSER_BACK },
149     { "Browser Forward", KEY_BROWSER_FORWARD },
150     { "Browser Refresh", KEY_BROWSER_REFRESH },
151     { "Browser Stop", KEY_BROWSER_STOP },
152     { "Browser Search", KEY_BROWSER_SEARCH },
153     { "Browser Favorites", KEY_BROWSER_FAVORITES },
154     { "Browser Home", KEY_BROWSER_HOME },
155     { "Volume Mute", KEY_VOLUME_MUTE },
156     { "Volume Down", KEY_VOLUME_DOWN },
157     { "Volume Up", KEY_VOLUME_UP },
158     { "Media Next Track", KEY_MEDIA_NEXT_TRACK },
159     { "Media Prev Track", KEY_MEDIA_PREV_TRACK },
160     { "Media Stop", KEY_MEDIA_STOP },
161     { "Media Play Pause", KEY_MEDIA_PLAY_PAUSE },
162     { "Mouse Wheel Up", KEY_MOUSEWHEELUP },
163     { "Mouse Wheel Down", KEY_MOUSEWHEELDOWN },
164     { "Mouse Wheel Left", KEY_MOUSEWHEELLEFT },
165     { "Mouse Wheel Right", KEY_MOUSEWHEELRIGHT },
166 };
167 enum { vlc_num_keys=sizeof(vlc_keys)/sizeof(struct key_descriptor_s) };
168
169 static int cmpkey (const void *key, const void *elem)
170 {
171     return ((uintptr_t)key) - ((key_descriptor_t *)elem)->i_key_code;
172 }
173
174 const char *KeyToString (uint_fast32_t sym)
175 {
176     key_descriptor_t *d;
177
178     d = (key_descriptor_t *)
179         bsearch ((void *)(uintptr_t)sym, vlc_keys, vlc_num_keys,
180                  sizeof (vlc_keys[0]), cmpkey);
181     return d ? d->psz_key_string : NULL;
182 }
183
184 uint_fast32_t StringToKey (char *name)
185 {
186     for (size_t i = 0; i < vlc_num_keys; i++)
187         if (!strcmp (vlc_keys[i].psz_key_string, name))
188             return vlc_keys[i].i_key_code;
189
190     return 0;
191 }
192
193 uint_fast32_t ConfigStringToKey (const char *name)
194 {
195     uint_fast32_t mods = 0;
196
197     const char *psz_parser = name;
198     for (;;)
199     {
200         psz_parser = strchr (psz_parser, '-');
201         if (psz_parser == NULL || psz_parser == name)
202             break;
203
204         for (size_t i = 0; i < vlc_num_modifiers; i++)
205         {
206             if (!strncasecmp (vlc_modifiers[i].psz_key_string, name,
207                               strlen (vlc_modifiers[i].psz_key_string)))
208             {
209                 mods |= vlc_modifiers[i].i_key_code;
210             }
211         }
212         name = psz_parser + 1;
213     }
214
215     for (size_t i = 0; i < vlc_num_keys; i++)
216         if (!strcasecmp( vlc_keys[i].psz_key_string, name))
217             return vlc_keys[i].i_key_code | mods;
218
219     return 0;
220 }
221
222 char *ConfigKeyToString (uint_fast32_t i_key)
223 {
224     // Worst case appears to be 45 characters:
225     // "Command-Meta-Ctrl-Shift-Alt-Browser Favorites"
226     char *psz_key = malloc (64);
227     if (!psz_key)
228         return NULL;
229
230     char *p = psz_key, *psz_end = psz_key + 54;
231     *p = '\0';
232
233     for (size_t i = 0; i < vlc_num_modifiers; i++)
234     {
235         if (i_key & vlc_modifiers[i].i_key_code)
236         {
237             p += snprintf (p, psz_end - p, "%s-",
238                            vlc_modifiers[i].psz_key_string);
239         }
240     }
241     for (size_t i = 0; i < vlc_num_keys; i++)
242     {
243         if ((i_key & ~KEY_MODIFIER) == vlc_keys[i].i_key_code)
244         {
245             p += snprintf (p, psz_end - p, "%s",
246                            vlc_keys[i].psz_key_string);
247             break;
248         }
249     }
250     return psz_key;
251 }