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"
36 typedef struct key_descriptor_s
38 const char *psz_key_string
;
42 static const struct key_descriptor_s vlc_modifiers
[] =
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
}
50 enum { vlc_num_modifiers
=sizeof(vlc_modifiers
)
51 /sizeof(struct key_descriptor_s
) };
53 static const struct key_descriptor_s vlc_keys
[] =
55 { "Unset", KEY_UNSET
},
56 { "Backspace", KEY_BACKSPACE
},
58 { "Enter", KEY_ENTER
},
62 { "Right", KEY_RIGHT
},
79 { "Insert", KEY_INSERT
},
80 { "Delete", KEY_DELETE
},
82 { "Page Up", KEY_PAGEUP
},
83 { "Page Down", KEY_PAGEDOWN
},
84 { "Browser Back", KEY_BROWSER_BACK
},
85 { "Browser Forward", KEY_BROWSER_FORWARD
},
86 { "Browser Refresh", KEY_BROWSER_REFRESH
},
87 { "Browser Stop", KEY_BROWSER_STOP
},
88 { "Browser Search", KEY_BROWSER_SEARCH
},
89 { "Browser Favorites", KEY_BROWSER_FAVORITES
},
90 { "Browser Home", KEY_BROWSER_HOME
},
91 { "Volume Mute", KEY_VOLUME_MUTE
},
92 { "Volume Down", KEY_VOLUME_DOWN
},
93 { "Volume Up", KEY_VOLUME_UP
},
94 { "Media Next Track", KEY_MEDIA_NEXT_TRACK
},
95 { "Media Prev Track", KEY_MEDIA_PREV_TRACK
},
96 { "Media Stop", KEY_MEDIA_STOP
},
97 { "Media Play Pause", KEY_MEDIA_PLAY_PAUSE
},
98 { "Mouse Wheel Up", KEY_MOUSEWHEELUP
},
99 { "Mouse Wheel Down", KEY_MOUSEWHEELDOWN
},
100 { "Mouse Wheel Left", KEY_MOUSEWHEELLEFT
},
101 { "Mouse Wheel Right", KEY_MOUSEWHEELRIGHT
},
103 enum { vlc_num_keys
=sizeof(vlc_keys
)/sizeof(struct key_descriptor_s
) };
105 static int cmpkey (const void *key
, const void *elem
)
107 return ((uintptr_t)key
) - ((key_descriptor_t
*)elem
)->i_key_code
;
110 /* Convert Unicode code point to UTF-8 */
111 static char *utf8_cp (uint_fast32_t cp
, char *buf
)
118 else if (cp
< (1 << 11))
121 buf
[1] = 0x80 | (cp
& 0x3F);
125 else if (cp
< (1 << 16))
128 buf
[2] = 0x80 | (cp
& 0x3F);
130 buf
[1] = 0x80 | (cp
& 0x3F);
134 else if (cp
< (1 << 21))
137 buf
[3] = 0x80 | (cp
& 0x3F);
139 buf
[2] = 0x80 | (cp
& 0x3F);
141 buf
[1] = 0x80 | (cp
& 0x3F);
150 /* Convert UTF-8 to Unicode code point */
151 static uint_fast32_t cp_utf8 (const char *utf8
)
154 size_t l
= strlen (utf8
);
156 if (f
< 0x80) /* ASCII (7 bits) */
158 if (f
< 0xC0 || l
< 2) /* bad */
160 if (f
< 0xE0) /* two bytes (11 bits) */
161 return ((f
& 0x1F) << 6) | (utf8
[1] & 0x3F);
164 if (f
< 0xF0) /* three bytes (16 bits) */
165 return ((f
& 0x0F) << 12) | ((utf8
[1] & 0x3F) << 6)
169 if (f
< 0xF8) /* four bytes (21 bits) */
170 return ((f
& 0x07) << 18) | ((utf8
[1] & 0x3F) << 12)
171 | ((utf8
[2] & 0x3F) << 6) | (utf8
[3] & 0x3F);
175 char *KeyToString (uint_fast32_t sym
)
179 d
= bsearch ((void *)(uintptr_t)sym
, vlc_keys
, vlc_num_keys
,
180 sizeof (vlc_keys
[0]), cmpkey
);
182 return strdup (d
->psz_key_string
);
185 if (utf8_cp (sym
, buf
))
191 uint_fast32_t StringToKey (char *name
)
193 for (size_t i
= 0; i
< vlc_num_keys
; i
++)
194 if (!strcmp (vlc_keys
[i
].psz_key_string
, name
))
195 return vlc_keys
[i
].i_key_code
;
197 return cp_utf8 (name
);
200 uint_fast32_t ConfigStringToKey (const char *name
)
202 uint_fast32_t mods
= 0;
206 const char *psz_parser
= strchr (name
, '-');
207 if (psz_parser
== NULL
|| psz_parser
== name
)
210 for (size_t i
= 0; i
< vlc_num_modifiers
; i
++)
212 if (!strncasecmp (vlc_modifiers
[i
].psz_key_string
, name
,
213 strlen (vlc_modifiers
[i
].psz_key_string
)))
215 mods
|= vlc_modifiers
[i
].i_key_code
;
218 name
= psz_parser
+ 1;
221 for (size_t i
= 0; i
< vlc_num_keys
; i
++)
222 if (!strcasecmp( vlc_keys
[i
].psz_key_string
, name
))
223 return vlc_keys
[i
].i_key_code
| mods
;
225 return cp_utf8 (name
) | mods
;
228 char *ConfigKeyToString (uint_fast32_t i_key
)
230 // Worst case appears to be 45 characters:
231 // "Command-Meta-Ctrl-Shift-Alt-Browser Favorites"
232 char *psz_key
= malloc (64);
236 char *p
= psz_key
, *psz_end
= psz_key
+ 54;
239 for (size_t i
= 0; i
< vlc_num_modifiers
; i
++)
241 if (i_key
& vlc_modifiers
[i
].i_key_code
)
243 p
+= snprintf (p
, psz_end
- p
, "%s-",
244 vlc_modifiers
[i
].psz_key_string
);
251 i_key
&= ~KEY_MODIFIER
;
252 d
= bsearch ((void *)(uintptr_t)i_key
, vlc_keys
, vlc_num_keys
,
253 sizeof (vlc_keys
[0]), cmpkey
);
255 p
+= snprintf (p
, psz_end
- p
, "%s", d
->psz_key_string
);
256 else if (utf8_cp (i_key
, buf
))
257 p
+= snprintf (p
, psz_end
- p
, "%s", buf
);