X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Faction.c;h=1f2657e1563d921a00de8f628a822b720c0643c2;hb=4bf223b66a90b3fcfb35d7ee35a1fc1cee1926e1;hp=e5eb94f8e58d2aeab124cc6bf65c70c826d4021f;hpb=469613e252bc8b0b22e883d88e0be0a6f7b0a4ff;p=vlc diff --git a/src/misc/action.c b/src/misc/action.c index e5eb94f8e5..1f2657e156 100644 --- a/src/misc/action.c +++ b/src/misc/action.c @@ -26,31 +26,109 @@ #include #include "../libvlc.h" #include +#include +#include -int vlc_key_to_action (vlc_object_t *libvlc, const char *varname, - vlc_value_t prevkey, vlc_value_t curkey, void *priv) +static int keycmp (const void *a, const void *b) { - const struct hotkey *key = priv; + const struct hotkey *ka = a, *kb = b; +#if (INT_MAX >= 0x7fffffff) + return ka->i_key - kb->i_key; +#else + return (ka->i_key < kb->i_key) ? -1 : (ka->i_key > kb->i_key) ? +1 : 0; +#endif +} + +/** + * 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) +{ + struct hotkey k = { .psz_action = NULL, .i_key = keycode, .i_action = 0 }; + const struct hotkey *key; + key = bsearch (&k, obj->p_libvlc->p_hotkeys, libvlc_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; - while (key->i_key != curkey.i_int) + 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; + + 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 = var_InheritInteger (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 } + qsort (keys, libvlc_actions_count, sizeof (*keys), keycmp); + + 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; + return strcmp(key, act->name); } vlc_key_t vlc_GetActionId(const char *name) { - for (size_t i = 0; i < libvlc_actions_count; i++) - if (!strcmp(libvlc_actions[i].name, name)) - return libvlc_actions[i].value; - return 0; + const struct action *act; + + act = bsearch(name, libvlc_actions, libvlc_actions_count, sizeof(*act), + actcmp); + return (act != NULL) ? act->value : ACTIONID_NONE; }