[vlc-commits] Store hotkey mappings in a tree instead of a table
Rémi Denis-Courmont
git at videolan.org
Sat Feb 12 22:57:38 CET 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 12 23:49:56 2011 +0200| [10fa1a40eee46b534be753600bb47b7d70392039] | committer: Rémi Denis-Courmont
Store hotkey mappings in a tree instead of a table
This avoids storing unmapping actions. More interestingly, this will
enable multiple keys per action.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=10fa1a40eee46b534be753600bb47b7d70392039
---
src/config/keys.c | 93 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 58 insertions(+), 35 deletions(-)
diff --git a/src/config/keys.c b/src/config/keys.c
index 36c2f84..f91ed5a 100644
--- a/src/config/keys.c
+++ b/src/config/keys.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <limits.h>
+#include <search.h>
#include <vlc_common.h>
#include <vlc_keys.h>
@@ -209,13 +210,13 @@ char *vlc_keycode2str (uint_fast32_t code)
}
-/**
- */
-typedef struct action
+/*** VLC key map ***/
+
+struct action
{
char name[24];
int value;
-} action_t;
+};
static const struct action actions[] =
{
@@ -324,49 +325,49 @@ static const struct action actions[] =
#define ACTIONS_COUNT (sizeof (actions) / sizeof (actions[0]))
+struct mapping
+{
+ uint32_t key; ///< Key code
+ vlc_key_t action; ///< Action ID
+};
+
static int keycmp (const void *a, const void *b)
{
- const struct hotkey *ka = a, *kb = b;
+ const struct mapping *ka = a, *kb = b;
+
#if (INT_MAX >= 0x7fffffff)
- return ka->i_key - kb->i_key;
+ return ka->key - kb->key;
#else
- return (ka->i_key < kb->i_key) ? -1 : (ka->i_key > kb->i_key) ? +1 : 0;
+ return (ka->key < kb->key) ? -1 : (ka->key > kb->key) ? +1 : 0;
#endif
}
struct vlc_actions
{
+ void *map; /* Key map */
struct hotkey keys[0];
};
-/**
- * Get the action ID associated with a VLC key code, if any.
- */
-static
-vlc_key_t vlc_TranslateKey (const vlc_object_t *obj, uint_fast32_t keycode)
-{
- struct hotkey k = { .psz_action = NULL, .i_key = keycode, .i_action = 0 };
- const struct hotkey *key;
-
- key = bsearch (&k, obj->p_libvlc->p_hotkeys, ACTIONS_COUNT,
- sizeof (*key), keycmp);
- return (key != NULL) ? key->i_action : ACTIONID_NONE;
-}
-
static int vlc_key_to_action (vlc_object_t *libvlc, const char *varname,
vlc_value_t prevkey, vlc_value_t curkey, void *d)
{
- (void)varname;
- (void)prevkey;
- (void)d;
+ const struct vlc_actions *as = d;
+ const struct mapping **pent;
+ uint32_t keycode = curkey.i_int;
- vlc_key_t action = vlc_TranslateKey (libvlc, curkey.i_int);
- if (!action)
+ pent = tfind (&keycode, &as->map, keycmp);
+ if (pent == NULL)
return VLC_SUCCESS;
- return var_SetInteger (libvlc, "key-action", action);
+
+ (void) varname;
+ (void) prevkey;
+ return var_SetInteger (libvlc, "key-action", (*pent)->action);
}
+/**
+ * Initializes the key map from configuration.
+ */
struct vlc_actions *vlc_InitActions (libvlc_int_t *libvlc)
{
struct hotkey *keys;
@@ -374,6 +375,7 @@ struct vlc_actions *vlc_InitActions (libvlc_int_t *libvlc)
if (unlikely(as == NULL))
return NULL;
+ as->map = NULL;
keys = as->keys;
var_Create (libvlc, "key-pressed", VLC_VAR_INTEGER);
@@ -382,12 +384,6 @@ struct vlc_actions *vlc_InitActions (libvlc_int_t *libvlc)
/* Initialize from configuration */
for (size_t i = 0; i < ACTIONS_COUNT; i++)
{
- char *str = var_InheritString (libvlc, actions[i].name);
- uint32_t code = str ? vlc_str2keycode (str) : KEY_UNSET;
-
- keys->psz_action = actions[i].name;
- keys->i_key = code;
- keys->i_action = actions[i].value;
#ifndef NDEBUG
if (i > 0
&& strcmp (actions[i-1].name, actions[i].name) >= 0)
@@ -397,12 +393,35 @@ struct vlc_actions *vlc_InitActions (libvlc_int_t *libvlc)
abort ();
}
#endif
+ keys->psz_action = actions[i].name;
+ keys->i_action = actions[i].value;
keys++;
+
+ char *str = var_InheritString (libvlc, actions[i].name);
+ uint32_t code = str ? vlc_str2keycode (str) : KEY_UNSET;
+
+ if (code == KEY_UNSET)
+ continue;
+
+ struct mapping *entry = malloc (sizeof (*entry));
+ if (entry == NULL)
+ continue;
+ entry->key = code;
+ entry->action = actions[i].value;
+
+ struct mapping **pent = tsearch (entry, &as->map, keycmp);
+ if (unlikely(pent == NULL))
+ continue;
+ if (*pent != entry)
+ {
+ free (entry);
+ msg_Warn (libvlc, "Key code \"%s\" bound to multiple actions",
+ str);
+ }
+ free (str);
}
- qsort (as->keys, ACTIONS_COUNT, sizeof (*keys), keycmp);
keys->psz_action = NULL;
- keys->i_key = 0;
keys->i_action = 0;
libvlc->p_hotkeys = as->keys;
@@ -410,12 +429,16 @@ struct vlc_actions *vlc_InitActions (libvlc_int_t *libvlc)
return VLC_SUCCESS;
}
+/**
+ * Destroys the key map.
+ */
void vlc_DeinitActions (libvlc_int_t *libvlc, struct vlc_actions *as)
{
if (unlikely(as == NULL))
return;
var_DelCallback (libvlc, "key-pressed", vlc_key_to_action, as);
+ tdestroy (as->map, free);
free (as);
libvlc->p_hotkeys = NULL;
}
More information about the vlc-commits
mailing list