From 646510099d5cf2963694b4ebe56220dce9645010 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 3 Jan 2010 16:08:00 +0200 Subject: [PATCH] Refactor key mapping internals --- src/libvlc.c | 36 ++-------------------- src/libvlc.h | 4 +-- src/misc/action.c | 76 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/libvlc.c b/src/libvlc.c index b04af7a618..358a298860 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -84,7 +84,6 @@ #include #include #include -#include #include "libvlc.h" @@ -811,36 +810,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, /* * Initialize hotkey handling */ - var_Create( p_libvlc, "key-pressed", VLC_VAR_INTEGER ); - var_Create( p_libvlc, "key-action", VLC_VAR_INTEGER ); - { - struct hotkey *p_keys = - malloc( (libvlc_actions_count + 1) * sizeof (*p_keys) ); - - /* Initialize from configuration */ - for( size_t i = 0; i < libvlc_actions_count; i++ ) - { - p_keys[i].psz_action = libvlc_actions[i].name; - p_keys[i].i_key = config_GetInt( p_libvlc, - libvlc_actions[i].name ); - p_keys[i].i_action = libvlc_actions[i].value; -#ifndef NDEBUG - if (i > 0 - && strcmp(libvlc_actions[i-1].name, libvlc_actions[i].name) >= 0) - { - msg_Err(p_libvlc, "%s and %s are not ordered properly", - libvlc_actions[i-1].name, libvlc_actions[i].name); - abort(); - } -#endif - } - p_keys[libvlc_actions_count].psz_action = NULL; - p_keys[libvlc_actions_count].i_key = 0; - p_keys[libvlc_actions_count].i_action = 0; - p_libvlc->p_hotkeys = p_keys; - var_AddCallback( p_libvlc, "key-pressed", vlc_key_to_action, - p_keys ); - } + vlc_InitActions( p_libvlc ); /* variables for signalling creation of new files */ var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING ); @@ -1104,9 +1074,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) /* Free module bank. It is refcounted, so we call this each time */ module_EndBank( p_libvlc, true ); - var_DelCallback( p_libvlc, "key-pressed", vlc_key_to_action, - (void *)p_libvlc->p_hotkeys ); - free( (void *)p_libvlc->p_hotkeys ); + vlc_DeinitActions( p_libvlc ); } /** diff --git a/src/libvlc.h b/src/libvlc.h index 47e86ccf37..0d94ed069c 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -35,8 +35,8 @@ typedef struct action } action_t; extern const struct action libvlc_actions[]; extern const size_t libvlc_actions_count; -extern int vlc_key_to_action (vlc_object_t *, const char *, - vlc_value_t, vlc_value_t, void *); +extern int vlc_InitActions (libvlc_int_t *); +extern void vlc_DeinitActions (libvlc_int_t *); /* * OS-specific initialization diff --git a/src/misc/action.c b/src/misc/action.c index 73cf2369b5..de943c9c18 100644 --- a/src/misc/action.c +++ b/src/misc/action.c @@ -28,25 +28,85 @@ #include #include -int vlc_key_to_action (vlc_object_t *libvlc, const char *varname, - vlc_value_t prevkey, vlc_value_t curkey, void *priv) +/** + * Get the action associated with a VLC key code, if any. + */ +static +vlc_key_t vlc_TranslateKey (const vlc_object_t *obj, uint_fast32_t keycode) { - const struct hotkey *key = priv; + /* TODO: search should be O(log n), not O(n) */ + for (const struct hotkey *key = obj->p_libvlc->p_hotkeys; + key->psz_action != NULL; + key++) + { + if (key->i_key == keycode) + return key->i_action; + } + return 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; + + vlc_key_t action = vlc_TranslateKey (libvlc, curkey.i_int); + if (!action) + return VLC_SUCCESS; + return var_SetInteger (libvlc, "key-action", action); +} + + +int vlc_InitActions (libvlc_int_t *libvlc) +{ + struct hotkey *keys; - while (key->i_key != curkey.i_int) + var_Create (libvlc, "key-pressed", VLC_VAR_INTEGER); + var_Create (libvlc, "key-action", VLC_VAR_INTEGER); + + keys = malloc ((libvlc_actions_count + 1) * sizeof (*keys)); + if (keys == NULL) { - if (key->psz_action == NULL) - return VLC_SUCCESS; /* key is not mapped to anything */ + libvlc->p_hotkeys = NULL; + return VLC_ENOMEM; + } - key++; + /* Initialize from configuration */ + for (size_t i = 0; i < libvlc_actions_count; i++) + { + keys[i].psz_action = libvlc_actions[i].name; + keys[i].i_key = config_GetInt (libvlc, libvlc_actions[i].name ); + keys[i].i_action = libvlc_actions[i].value; +#ifndef NDEBUG + if (i > 0 + && strcmp (libvlc_actions[i-1].name, libvlc_actions[i].name) >= 0) + { + msg_Err (libvlc, "%s and %s are not ordered properly", + libvlc_actions[i-1].name, libvlc_actions[i].name); + abort (); + } +#endif } + keys[libvlc_actions_count].psz_action = NULL; + keys[libvlc_actions_count].i_key = 0; + keys[libvlc_actions_count].i_action = 0; - return var_SetInteger (libvlc, "key-action", key->i_action); + libvlc->p_hotkeys = keys; + var_AddCallback (libvlc, "key-pressed", vlc_key_to_action, NULL); + return VLC_SUCCESS; } +void vlc_DeinitActions (libvlc_int_t *libvlc) +{ + if (unlikely(libvlc->p_hotkeys == NULL)) + return; + var_DelCallback (libvlc, "key-pressed", vlc_key_to_action, NULL); + free ((void *)libvlc->p_hotkeys); +} + + static int actcmp(const void *key, const void *ent) { const struct action *act = ent; -- 2.39.2