Refactor key mapping internals
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 3 Jan 2010 14:08:00 +0000 (16:08 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 3 Jan 2010 14:37:32 +0000 (16:37 +0200)
src/libvlc.c
src/libvlc.h
src/misc/action.c

index b04af7a..358a298 100644 (file)
@@ -84,7 +84,6 @@
 #include <vlc_charset.h>
 #include <vlc_cpu.h>
 #include <vlc_url.h>
-#include <vlc_keys.h>
 
 #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 );
 }
 
 /**
index 47e86cc..0d94ed0 100644 (file)
@@ -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
index 73cf236..de943c9 100644 (file)
 #include <vlc_keys.h>
 #include <stdlib.h>
 
-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;