[vlc-devel] [PATCH 12/22] actions: add vlc_actions_get_keycodes

Hugo Beauzée-Luyssen hugo at beauzee.fr
Mon Aug 7 18:53:15 CEST 2017


From: Thomas Guillem <thomas at gllm.fr>

Difference with previous version:
- Handle multiple key combination for the same action
---
 include/vlc_actions.h                 |  10 +++
 modules/control/globalhotkeys/win32.c | 116 ++++++++++++++++------------------
 modules/control/globalhotkeys/xcb.c   |  75 +++++++++++-----------
 src/libvlccore.sym                    |   1 +
 src/misc/actions.c                    |  39 ++++++++++++
 5 files changed, 142 insertions(+), 99 deletions(-)

diff --git a/include/vlc_actions.h b/include/vlc_actions.h
index 685264897a..404c1662a8 100644
--- a/include/vlc_actions.h
+++ b/include/vlc_actions.h
@@ -255,6 +255,16 @@ VLC_API vlc_action_id_t
 vlc_actions_get_id(const char *psz_key_name);
 
 /**
+ * Get keycodes from a action key name and vlc configuration
+ * \return The number of keycodes for this action, or 0 in case of an error.
+ * The list needs to be released with free()
+ */
+VLC_API size_t
+vlc_actions_get_keycodes(vlc_object_t *p_obj, const char *psz_key_name,
+                        bool b_global, uint_fast32_t **pp_keycodes );
+#define vlc_actions_get_keycodes(a, b, c, d) vlc_actions_get_keycodes(VLC_OBJECT(a), b, c, d)
+
+/**
  * Get a list a key names
  * \return A NULL terminated list of const char *
  */
diff --git a/modules/control/globalhotkeys/win32.c b/modules/control/globalhotkeys/win32.c
index ff3f3bac61..e20d776d90 100644
--- a/modules/control/globalhotkeys/win32.c
+++ b/modules/control/globalhotkeys/win32.c
@@ -170,22 +170,16 @@ static void *Thread( void *p_data )
     for( const char* const* ppsz_keys = vlc_actions_get_key_names( p_intf );
          *ppsz_keys != NULL; ppsz_keys++ )
     {
-        char varname[12 + strlen( *ppsz_keys )];
-        sprintf( varname, "global-key-%s", *ppsz_keys );
-
-        char *key = var_InheritString( p_intf, varname );
-        if( key == NULL )
-            continue;
-
-        UINT i_key = vlc_str2keycode( key );
-        free( key );
-        if( i_key == KEY_UNSET )
-            continue;
-
-        UINT i_keyMod = 0;
-        if( i_key & KEY_MODIFIER_SHIFT ) i_keyMod |= MOD_SHIFT;
-        if( i_key & KEY_MODIFIER_ALT ) i_keyMod |= MOD_ALT;
-        if( i_key & KEY_MODIFIER_CTRL ) i_keyMod |= MOD_CONTROL;
+        uint_fast32_t *p_keys;
+        size_t i_nb_keys = vlc_actions_get_keycodes( p_intf, *ppsz_keys, true,
+                                                     &p_keys );
+        for( size_t i = 0; i < i_nb_keys; ++i )
+        {
+            uint_fast32_t i_key = p_keys[i];
+            UINT i_keyMod = 0;
+            if( i_key & KEY_MODIFIER_SHIFT ) i_keyMod |= MOD_SHIFT;
+            if( i_key & KEY_MODIFIER_ALT ) i_keyMod |= MOD_ALT;
+            if( i_key & KEY_MODIFIER_CTRL ) i_keyMod |= MOD_CONTROL;
 
 #define HANDLE( key ) case KEY_##key: i_vk = VK_##key; break
 #define HANDLE2( key, key2 ) case KEY_##key: i_vk = VK_##key2; break
@@ -209,55 +203,57 @@ static void *Thread( void *p_data )
 #define VK_PAGEDOWN             0x22
 #endif
 
-        UINT i_vk = 0;
-        switch( i_key & ~KEY_MODIFIER )
-        {
-            HANDLE( LEFT );
-            HANDLE( RIGHT );
-            HANDLE( UP );
-            HANDLE( DOWN );
-            HANDLE( SPACE );
-            HANDLE2( ESC, ESCAPE );
-            HANDLE2( ENTER, RETURN );
-            HANDLE( F1 );
-            HANDLE( F2 );
-            HANDLE( F3 );
-            HANDLE( F4 );
-            HANDLE( F5 );
-            HANDLE( F6 );
-            HANDLE( F7 );
-            HANDLE( F8 );
-            HANDLE( F9 );
-            HANDLE( F10 );
-            HANDLE( F11 );
-            HANDLE( F12 );
-            HANDLE( PAGEUP );
-            HANDLE( PAGEDOWN );
-            HANDLE( HOME );
-            HANDLE( END );
-            HANDLE( INSERT );
-            HANDLE( DELETE );
-            HANDLE( VOLUME_DOWN );
-            HANDLE( VOLUME_UP );
-            HANDLE( MEDIA_PLAY_PAUSE );
-            HANDLE( MEDIA_STOP );
-            HANDLE( MEDIA_PREV_TRACK );
-            HANDLE( MEDIA_NEXT_TRACK );
-
-            default:
-                i_vk = toupper( (uint8_t)(i_key & ~KEY_MODIFIER) );
-                break;
-        }
-        if( !i_vk ) continue;
+            UINT i_vk = 0;
+            switch( i_key & ~KEY_MODIFIER )
+            {
+                HANDLE( LEFT );
+                HANDLE( RIGHT );
+                HANDLE( UP );
+                HANDLE( DOWN );
+                HANDLE( SPACE );
+                HANDLE2( ESC, ESCAPE );
+                HANDLE2( ENTER, RETURN );
+                HANDLE( F1 );
+                HANDLE( F2 );
+                HANDLE( F3 );
+                HANDLE( F4 );
+                HANDLE( F5 );
+                HANDLE( F6 );
+                HANDLE( F7 );
+                HANDLE( F8 );
+                HANDLE( F9 );
+                HANDLE( F10 );
+                HANDLE( F11 );
+                HANDLE( F12 );
+                HANDLE( PAGEUP );
+                HANDLE( PAGEDOWN );
+                HANDLE( HOME );
+                HANDLE( END );
+                HANDLE( INSERT );
+                HANDLE( DELETE );
+                HANDLE( VOLUME_DOWN );
+                HANDLE( VOLUME_UP );
+                HANDLE( MEDIA_PLAY_PAUSE );
+                HANDLE( MEDIA_STOP );
+                HANDLE( MEDIA_PREV_TRACK );
+                HANDLE( MEDIA_NEXT_TRACK );
+
+                default:
+                    i_vk = toupper( (uint8_t)(i_key & ~KEY_MODIFIER) );
+                    break;
+            }
+            if( !i_vk ) continue;
 
 #undef HANDLE
 #undef HANDLE2
 
-        ATOM atom = GlobalAddAtomA( *ppsz_keys );
-        if( !atom ) continue;
+            ATOM atom = GlobalAddAtomA( *ppsz_keys );
+            if( !atom ) continue;
 
-        if( !RegisterHotKey( p_sys->hotkeyWindow, atom, i_keyMod, i_vk ) )
-            GlobalDeleteAtom( atom );
+            if( !RegisterHotKey( p_sys->hotkeyWindow, atom, i_keyMod, i_vk ) )
+                GlobalDeleteAtom( atom );
+            free( p_keys );
+        }
     }
 
     /* Main message loop */
diff --git a/modules/control/globalhotkeys/xcb.c b/modules/control/globalhotkeys/xcb.c
index fb85377383..cc3dc688e1 100644
--- a/modules/control/globalhotkeys/xcb.c
+++ b/modules/control/globalhotkeys/xcb.c
@@ -293,52 +293,49 @@ static bool Mapping( intf_thread_t *p_intf )
     for( const char* const* ppsz_keys = vlc_actions_get_key_names( p_intf );
          *ppsz_keys != NULL; ppsz_keys++ )
     {
-        char varname[12 + strlen( *ppsz_keys )];
-        sprintf( varname, "global-key-%s", *ppsz_keys );
+        uint_fast32_t *p_keys;
+        size_t i_nb_keys = vlc_actions_get_keycodes( p_intf, *ppsz_keys, true,
+                                                     &p_keys );
 
-        char *key = var_InheritString( p_intf, varname );
-        if( key == NULL )
-            continue;
-
-        uint_fast32_t i_vlc_key = vlc_str2keycode( key );
-        free( key );
-        if( i_vlc_key == KEY_UNSET )
-            continue;
-
-        const unsigned i_modifier = GetX11Modifier( p_sys->p_connection,
-                p_sys->p_symbols, i_vlc_key & KEY_MODIFIER );
-
-        const size_t max = sizeof(p_x11_modifier_ignored) /
-                sizeof(*p_x11_modifier_ignored);
-        for( unsigned int i = 0; i < max; i++ )
+        for( size_t i = 0; i < i_nb_keys; ++i )
         {
-            const unsigned i_ignored = GetModifier( p_sys->p_connection,
-                    p_sys->p_symbols, p_x11_modifier_ignored[i] );
-            if( i != 0 && i_ignored == 0)
-                continue;
+            uint_fast32_t i_vlc_key = p_keys[i];
+            const unsigned i_modifier = GetX11Modifier( p_sys->p_connection,
+                    p_sys->p_symbols, i_vlc_key & KEY_MODIFIER );
+
+            const size_t max = sizeof(p_x11_modifier_ignored) /
+                    sizeof(*p_x11_modifier_ignored);
+            for( unsigned int i = 0; i < max; i++ )
+            {
+                const unsigned i_ignored = GetModifier( p_sys->p_connection,
+                        p_sys->p_symbols, p_x11_modifier_ignored[i] );
+                if( i != 0 && i_ignored == 0)
+                    continue;
 
-            xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode(
-                p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) );
+                xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode(
+                    p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) );
 
-            if( !p_keys )
-                break;
+                if( !p_keys )
+                    break;
 
-            hotkey_mapping_t *p_map = realloc( p_sys->p_map,
-                              sizeof(*p_sys->p_map) * (p_sys->i_map+1) );
-            if( !p_map )
-            {
-                free( p_keys );
-                break;
+                hotkey_mapping_t *p_map = realloc( p_sys->p_map,
+                                  sizeof(*p_sys->p_map) * (p_sys->i_map+1) );
+                if( !p_map )
+                {
+                    free( p_keys );
+                    break;
+                }
+                p_sys->p_map = p_map;
+                p_map += p_sys->i_map;
+                p_sys->i_map++;
+
+                p_map->p_keys = p_keys;
+                p_map->i_modifier = i_modifier|i_ignored;
+                p_map->i_vlc = i_vlc_key;
+                active = true;
             }
-            p_sys->p_map = p_map;
-            p_map += p_sys->i_map;
-            p_sys->i_map++;
-
-            p_map->p_keys = p_keys;
-            p_map->i_modifier = i_modifier|i_ignored;
-            p_map->i_vlc = i_vlc_key;
-            active = true;
         }
+        free( p_keys );
     }
     return active;
 }
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index a24cc0a4d5..f9a82d7a51 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -512,6 +512,7 @@ video_format_Setup
 video_format_Print
 vlc_actions_get_id
 vlc_actions_get_key_names
+vlc_actions_get_keycodes
 vlc_b64_decode
 vlc_b64_decode_binary
 vlc_b64_decode_binary_to_buffer
diff --git a/src/misc/actions.c b/src/misc/actions.c
index 1905b978c1..74585f6c70 100644
--- a/src/misc/actions.c
+++ b/src/misc/actions.c
@@ -594,6 +594,45 @@ vlc_actions_get_id (const char *name)
     return (act != NULL) ? act->id : ACTIONID_NONE;
 }
 
+#undef vlc_actions_get_keycodes
+size_t
+vlc_actions_get_keycodes(vlc_object_t *p_obj, const char *psz_key_name,
+                        bool b_global, uint_fast32_t **pp_keycodes)
+{
+    char varname[12 /* "global-key-" */ + strlen( psz_key_name )];
+    sprintf( varname, "%skey-%s", b_global ? "global-" : "", psz_key_name );
+
+    *pp_keycodes = NULL;
+
+    char *psz_keys = var_InheritString( p_obj, varname );
+    if( psz_keys == NULL )
+        return 0;
+
+    size_t i_nb_keycodes = 0;
+    for( const char* psz_it = psz_keys; *psz_it; ++psz_it )
+    {
+        if( *psz_it == '\t' )
+            ++i_nb_keycodes;
+    }
+    ++i_nb_keycodes;
+    *pp_keycodes = malloc( i_nb_keycodes * sizeof( **pp_keycodes ) );
+    if( unlikely( !*pp_keycodes ) )
+    {
+        free( psz_keys );
+        return 0;
+    }
+    size_t i = 0;
+    for( char *buf, *key = strtok_r( psz_keys, "\t", &buf );
+         key != NULL;
+         key = strtok_r( NULL, "\t", &buf ), ++i )
+    {
+        (*pp_keycodes)[i] = vlc_str2keycode( key );
+    }
+    assert( i == i_nb_keycodes );
+    free( psz_keys );
+    return i_nb_keycodes;
+}
+
 #undef vlc_actions_get_key_names
 const char* const*
 vlc_actions_get_key_names(vlc_object_t *p_obj)
-- 
2.11.0



More information about the vlc-devel mailing list