]> git.sesse.net Git - vlc/blobdiff - modules/control/globalhotkeys/xcb.c
XCB global hotkeys: don't bother unregistering
[vlc] / modules / control / globalhotkeys / xcb.c
index f1ab4fcb38062a9b32fd375a03eec597dc13fffc..8fe4167f8141a470703aaa2d29c33b0f6dd6e3dd 100644 (file)
@@ -78,9 +78,8 @@ struct intf_sys_t
     hotkey_mapping_t *p_map;
 };
 
-static void Mapping( intf_thread_t *p_intf );
+static bool Mapping( intf_thread_t *p_intf );
 static void Register( intf_thread_t *p_intf );
-static void Unregister( intf_thread_t *p_intf );
 static void *Thread( void *p_data );
 
 /*****************************************************************************
@@ -90,6 +89,7 @@ static int Open( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
     intf_sys_t *p_sys;
+    int ret = VLC_EGENERIC;
 
     p_intf->p_sys = p_sys = calloc( 1, sizeof(*p_sys) );
     if( !p_sys )
@@ -101,7 +101,7 @@ static int Open( vlc_object_t *p_this )
     p_sys->p_connection = xcb_connect( psz_display, &i_screen_default );
     free( psz_display );
 
-    if( !p_sys->p_connection )
+    if( xcb_connection_has_error( p_sys->p_connection ) )
         goto error;
 
     /* Get the root windows of the default screen */
@@ -124,12 +124,16 @@ static int Open( vlc_object_t *p_this )
     if( !p_sys->p_symbols )
         goto error;
 
-    Mapping( p_intf );
+    if( !Mapping( p_intf ) )
+    {
+        ret = VLC_SUCCESS;
+        p_intf->p_sys = NULL; /* for Close() */
+        goto error;
+    }
     Register( p_intf );
 
     if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
     {
-        Unregister( p_intf );
 #ifndef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
         if( p_sys->p_map )
             free( p_sys->p_map->p_keys );
@@ -142,10 +146,9 @@ static int Open( vlc_object_t *p_this )
 error:
     if( p_sys->p_symbols )
         xcb_key_symbols_free( p_sys->p_symbols );
-    if( p_sys->p_connection )
-        xcb_disconnect( p_sys->p_connection );
+    xcb_disconnect( p_sys->p_connection );
     free( p_sys );
-    return VLC_EGENERIC;
+    return ret;
 }
 
 /*****************************************************************************
@@ -156,10 +159,12 @@ static void Close( vlc_object_t *p_this )
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
     intf_sys_t *p_sys = p_intf->p_sys;
 
+    if( !p_sys )
+        return; /* if we were running disabled */
+
     vlc_cancel( p_sys->thread );
     vlc_join( p_sys->thread, NULL );
 
-    Unregister( p_intf );
 #ifndef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
     if( p_sys->p_map )
         free( p_sys->p_map->p_keys );
@@ -182,6 +187,9 @@ static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *
         XCB_MOD_MASK_4, XCB_MOD_MASK_5
     };
 
+    if( sym == 0 )
+        return 0; /* no modifier */
+
 #ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
     const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_symbols, sym );
     if( key == 0 )
@@ -190,6 +198,21 @@ static unsigned GetModifier( xcb_connection_t *p_connection, xcb_key_symbols_t *
     const xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode( p_symbols, sym );
     if( !p_keys )
         return 0;
+
+    int i = 0;
+    bool no_modifier = true;
+    while( p_keys[i] != XCB_NO_SYMBOL )
+    {
+        if( p_keys[i] != 0 )
+        {
+            no_modifier = false;
+            break;
+        }
+        i++;
+    }
+
+    if( no_modifier )
+        return 0;
 #endif
 
     xcb_get_modifier_mapping_cookie_t r =
@@ -297,7 +320,7 @@ static xcb_keysym_t GetX11Key( unsigned i_vlc )
     return XK_VoidSymbol;
 }
 
-static void Mapping( intf_thread_t *p_intf )
+static bool Mapping( intf_thread_t *p_intf )
 {
     static const xcb_keysym_t p_x11_modifier_ignored[] = {
         0,
@@ -307,6 +330,7 @@ static void Mapping( intf_thread_t *p_intf )
     };
 
     intf_sys_t *p_sys = p_intf->p_sys;
+    bool active = false;
 
     p_sys->i_map = 0;
     p_sys->p_map = NULL;
@@ -344,7 +368,7 @@ static void Mapping( intf_thread_t *p_intf )
         {
             const unsigned i_ignored = GetModifier( p_sys->p_connection,
                     p_sys->p_symbols, p_x11_modifier_ignored[i] );
-            if( i != 0 && i_ignored == 0x00)
+            if( i != 0 && i_ignored == 0)
                 continue;
 
             hotkey_mapping_t *p_map_old = p_sys->p_map;
@@ -364,8 +388,10 @@ static void Mapping( intf_thread_t *p_intf )
 #endif
             p_map->i_modifier = i_modifier|i_ignored;
             p_map->i_action = i_vlc_action;
+            active = true;
         }
     }
+    return active;
 }
 
 static void Register( intf_thread_t *p_intf )
@@ -389,23 +415,6 @@ static void Register( intf_thread_t *p_intf )
 #endif
     }
 }
-static void Unregister( intf_thread_t *p_intf )
-{
-    intf_sys_t *p_sys = p_intf->p_sys;
-
-    for( int i = 0; i < p_sys->i_map; i++ )
-    {
-        const hotkey_mapping_t *p_map = &p_sys->p_map[i];
-#ifdef XCB_KEYSYM_OLD_API /* as seen in Debian Lenny */
-        xcb_ungrab_key( p_sys->p_connection, p_map->i_x11, p_sys->root,
-                p_map->i_modifier );
-#else
-        for( int j = 0; p_map->p_keys[j] != XCB_NO_SYMBOL; j++ )
-            xcb_ungrab_key( p_sys->p_connection, p_map->p_keys[j], p_sys->root,
-                    p_map->i_modifier );
-#endif
-    }
-}
 
 static void *Thread( void *p_data )
 {