]> git.sesse.net Git - vlc/commitdiff
src/libvlc.c:
authorSigmund Augdal Helberg <sigmunau@videolan.org>
Sun, 26 Oct 2003 12:46:55 +0000 (12:46 +0000)
committerSigmund Augdal Helberg <sigmunau@videolan.org>
Sun, 26 Oct 2003 12:46:55 +0000 (12:46 +0000)
 * created a variable "key-pressed" in p_vlc that can be used to
   report or read key presses
 * allways try to start hotkeys interface in the background
configure.ac, modules/control/Modules.am, modules/control/hotkeys.c:
 * a new control module that reads keypresses from "key-pressed" and
   performs an action depending on what is asosiated with this key.
   Also uses nice on screen messages to indicate what action was performed
modules/video_filter/filter_common.h:
 * removed code to pass old style key reporting through filters
modules/video_output/x11/xcommon.c:
 * report key-presses through the new mechanism. Incomplete, I need help
   with this.

configure.ac
modules/control/Modules.am
modules/control/hotkeys.c [new file with mode: 0755]
modules/video_filter/filter_common.h
modules/video_output/x11/xcommon.c
src/libvlc.c

index 6c0a061ae02e9dc31449fae0ec379dd95739253f..37897fbdc34f72805a9b6a69014155008392fd5f 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.94 2003/10/24 21:27:06 gbazin Exp $
+dnl $Id: configure.ac,v 1.95 2003/10/26 12:46:55 sigmunau Exp $
 
 AC_INIT(vlc,0.6.3-cvs)
 
@@ -844,7 +844,7 @@ test "${enable_cprof}" != "yes" && enable_cprof="no"
 dnl
 dnl  default modules
 dnl
-AX_ADD_PLUGINS([dummy rc logger gestures memcpy])
+AX_ADD_PLUGINS([dummy rc logger gestures memcpy hotkeys])
 AX_ADD_PLUGINS([es mpga m4v mpeg_system ps ts avi asf aac mp4 rawdv])
 AX_ADD_PLUGINS([spudec mpeg_audio lpcm a52 dts cinepak])
 AX_ADD_PLUGINS([deinterlace invert adjust wall transform distort clone crop motionblur])
index 557cd52a01cdac2dda836df72d941a352697567b..8a1e55694a5628a2cc6d8ec423e1803b94df8841 100644 (file)
@@ -2,3 +2,4 @@ SOURCES_gestures = gestures.c
 SOURCES_http = http.c
 SOURCES_ntservice = ntservice.c
 SOURCES_joystick = joystick.c
+SOURCES_hotkeys = hotkeys.c
diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c
new file mode 100755 (executable)
index 0000000..d52a69e
--- /dev/null
@@ -0,0 +1,356 @@
+/*****************************************************************************
+ * hotkeys.c: Hotkey handling for vlc
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: hotkeys.c,v 1.1 2003/10/26 12:46:55 sigmunau Exp $
+ *
+ * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <string.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <vlc/vout.h>
+#include <vlc/aout.h>
+#include <osd.h>
+
+#define BUFFER_SIZE 10
+/*****************************************************************************
+ * intf_sys_t: description and status of FB interface
+ *****************************************************************************/
+struct intf_sys_t
+{
+    vlc_mutex_t         change_lock;  /* mutex to keep the callback
+                                       * and the main loop from
+                                       * stepping on each others
+                                       * toes */
+    int                 p_keys[ BUFFER_SIZE ]; /* buffer that contains
+                                                * keyevents */
+    int                 i_size;        /* number of events in buffer */
+    input_thread_t *    p_input;       /* pointer to input */
+    vout_thread_t *     p_vout;        /* pointer to vout object */
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Open    ( vlc_object_t * );
+static void Close   ( vlc_object_t * );
+static void Run     ( intf_thread_t * );
+static void Feedback( intf_thread_t *, char * );
+static int  GetKey  ( intf_thread_t *);
+static int  KeyEvent( vlc_object_t *, char const *,
+                      vlc_value_t, vlc_value_t, void * );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( _("hotkey interface") );
+    set_capability( "interface", 0 );
+    set_callbacks( Open, Close );
+vlc_module_end();
+
+/*****************************************************************************
+ * Open: initialize interface
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        msg_Err( p_intf, "out of memory" );
+        return 1;
+    }
+    vlc_mutex_init( p_intf, &p_intf->p_sys->change_lock );
+    p_intf->p_sys->i_size = 0;
+    p_intf->pf_run = Run;
+
+    p_intf->p_sys->p_input = NULL;
+    p_intf->p_sys->p_vout = NULL;
+    var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
+    return 0;
+}
+
+/*****************************************************************************
+ * Close: destroy interface
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_this;
+
+    if( p_intf->p_sys->p_input )
+    {
+        vlc_object_release( p_intf->p_sys->p_input );
+    }
+    if( p_intf->p_sys->p_vout )
+    {
+        vlc_object_release( p_intf->p_sys->p_vout );
+    }
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * Run: main loop
+ *****************************************************************************/
+static void Run( intf_thread_t *p_intf )
+{
+    playlist_t *p_playlist;
+    input_thread_t *p_input;
+    vout_thread_t *p_vout = NULL;
+    int i_fullscreen = config_GetInt( p_intf, "fullscreen-key" );
+    int i_quit = config_GetInt( p_intf, "quit-key" );
+    int i_vol_up = config_GetInt( p_intf, "vol-up-key" );
+    int i_vol_down = config_GetInt( p_intf, "vol-down-key" );
+    int i_play_pause = config_GetInt( p_intf, "play-pause-key" );    
+    int i_play = config_GetInt( p_intf, "play-key" );    
+    int i_pause = config_GetInt( p_intf, "pause-key" );    
+    int i_stop = config_GetInt( p_intf, "stop-key" );
+    int i_next = config_GetInt( p_intf, "next-key" );
+    int i_prev = config_GetInt( p_intf, "prev-key" );
+    int i_faster = config_GetInt( p_intf, "faster-key" );
+    int i_slower = config_GetInt( p_intf, "slower-key" );
+    int i_key = 0;
+    
+    while( !p_intf->b_die )
+    {
+        /* Sleep a bit */
+        msleep( INTF_IDLE_SLEEP );
+
+        /* Update the input */
+        if( p_intf->p_sys->p_input == NULL )
+        {
+            p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+                                                      FIND_ANYWHERE );
+        }
+        else if( p_intf->p_sys->p_input->b_dead )
+        {
+            vlc_object_release( p_intf->p_sys->p_input );
+            p_intf->p_sys->p_input = NULL;
+        }
+        p_input = p_intf->p_sys->p_input;
+
+        /* Update the vout */
+        if( p_vout == NULL )
+        {
+            p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+                                      FIND_ANYWHERE );
+            p_intf->p_sys->p_vout = p_vout;
+        }
+        else if( p_vout->b_die )
+        {
+            vlc_object_release( p_vout );
+            p_vout = NULL;
+            p_intf->p_sys->p_vout = NULL;
+        }
+
+        i_key = GetKey( p_intf );
+        if ( !i_key )
+        {
+            /* No key pressed, sleep a bit more */
+            msleep( INTF_IDLE_SLEEP );
+            continue;
+        }
+        if( i_key == i_quit )
+        {
+            p_intf->p_vlc->b_die = VLC_TRUE;
+            Feedback( p_intf, _("Quit" ) );
+            continue;
+        }
+        if( i_key == i_vol_up )
+        {
+            audio_volume_t i_newvol;
+            char string[9];
+            aout_VolumeUp( p_intf, 1, &i_newvol );
+            sprintf( string, "Vol %%%d", i_newvol*100/AOUT_VOLUME_MAX );
+            Feedback( p_intf, string );
+        }
+        if( i_key == i_vol_down )
+        {
+            audio_volume_t i_newvol;
+            char string[9];
+            aout_VolumeDown( p_intf, 1, &i_newvol );
+            sprintf( string, "Vol %%%d", i_newvol*100/AOUT_VOLUME_MAX );
+            Feedback( p_intf, string );
+        }
+        if( p_vout )
+        {
+            if( i_key == i_fullscreen )
+            {
+                p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                continue;
+            }
+        }
+            
+        if( i_key == i_play )
+        {
+            p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                          FIND_ANYWHERE );
+            if( p_playlist )
+            {
+                vlc_mutex_lock( &p_playlist->object_lock );
+                if( p_playlist->i_size )
+                {
+                    vlc_mutex_unlock( &p_playlist->object_lock );
+                    playlist_Play( p_playlist );
+                    vlc_object_release( p_playlist );
+                }
+            }
+            continue;
+        }
+            
+        if( i_key == i_play_pause )
+        {
+            if( p_input &&
+                p_input->stream.control.i_status != PAUSE_S )
+            {
+                Feedback( p_intf, _( "Pause" ) );
+                input_SetStatus( p_input, INPUT_STATUS_PAUSE );
+            }
+            else
+            {
+                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                              FIND_ANYWHERE );
+                if( p_playlist )
+                {
+                    vlc_mutex_lock( &p_playlist->object_lock );
+                    if( p_playlist->i_size )
+                    {
+                        vlc_mutex_unlock( &p_playlist->object_lock );
+                        Feedback( p_intf, _( "Play" ) );
+                        playlist_Play( p_playlist );
+                        vlc_object_release( p_playlist );
+                    }
+                }
+            }                    
+            continue;
+        }
+            
+        else if( p_input )
+        {
+            if( i_key == i_pause )
+            {
+                Feedback( p_intf, _( "Pause" ) );
+                input_SetStatus( p_input, INPUT_STATUS_PAUSE );
+            }
+            else if( i_key == i_next )
+            {
+                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                              FIND_ANYWHERE );
+                if( p_playlist )
+                {
+                    playlist_Next( p_playlist );
+                    vlc_object_release( p_playlist );
+                }
+            }
+            else if( i_key == i_prev )
+            {
+                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                              FIND_ANYWHERE );
+                if( p_playlist )
+                {
+                    playlist_Prev( p_playlist );
+                    vlc_object_release( p_playlist );
+                }
+            }
+            else if( i_key == i_stop )
+            {
+                p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                              FIND_ANYWHERE );
+                if( p_playlist )
+                {
+                    playlist_Stop( p_playlist );
+                    vlc_object_release( p_playlist );
+                }
+            }
+            else if( i_key == i_faster )
+            {
+                input_SetStatus( p_input, INPUT_STATUS_FASTER );
+            }
+            else if( i_key == i_slower )
+            {
+                input_SetStatus( p_input, INPUT_STATUS_SLOWER );
+            }
+        }
+
+    }
+}
+
+static void Feedback( intf_thread_t *p_intf, char *psz_string )
+{
+    if ( p_intf->p_sys->p_vout )
+    {
+       vout_ShowTextRelative( p_intf->p_sys->p_vout, psz_string, NULL, 
+                                OSD_ALIGN_TOP|OSD_ALIGN_RIGHT, 30,20,400000 );
+    }
+}
+
+static int  GetKey  ( intf_thread_t *p_intf)
+{
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
+    if ( p_intf->p_sys->i_size == 0 )
+    {
+        vlc_mutex_unlock( &p_intf->p_sys->change_lock );
+        return 0;
+    }
+    else
+    {
+        int i_return = p_intf->p_sys->p_keys[ 0 ];
+        int i;
+        p_intf->p_sys->i_size--;
+        for ( i = 0; i < BUFFER_SIZE - 1; i++)
+        {
+            p_intf->p_sys->p_keys[ i ] = p_intf->p_sys->p_keys[ i + 1 ];
+        }
+        vlc_mutex_unlock( &p_intf->p_sys->change_lock );
+        return i_return;
+    }
+}
+
+/*****************************************************************************
+ * KeyEvent: callback for keyboard events
+ *****************************************************************************/
+static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
+                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)p_data;
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
+    if ( p_intf->p_sys->i_size == BUFFER_SIZE )
+    {
+        msg_Warn( p_intf, "Event buffer full, dropping keypress" );
+        vlc_mutex_unlock( &p_intf->p_sys->change_lock );
+        return VLC_EGENERIC;
+    }
+    else
+    {
+        p_intf->p_sys->p_keys[ p_intf->p_sys->i_size ] = newval.i_int;
+        p_intf->p_sys->i_size++;
+    }            
+    vlc_mutex_unlock( &p_intf->p_sys->change_lock );
+
+    return VLC_SUCCESS;
+}
+
index 97858608548aeb2fbb92b0206be5e59adf1c655d..e0f00d3c883dc285820045671c5a0a84832cc852 100644 (file)
@@ -2,7 +2,7 @@
  * filter_common.h: Common filter functions
  *****************************************************************************
  * Copyright (C) 2001, 2002, 2003 VideoLAN
- * $Id: filter_common.h,v 1.4 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: filter_common.h,v 1.5 2003/10/26 12:46:55 sigmunau Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -78,16 +78,14 @@ static int SetParentVal( vlc_object_t *p_this, char const *psz_var,
     var_AddCallback( newvout, "mouse-x", SendEvents, p_vout );                \
     var_AddCallback( newvout, "mouse-y", SendEvents, p_vout );                \
     var_AddCallback( newvout, "mouse-moved", SendEvents, p_vout );            \
-    var_AddCallback( newvout, "mouse-clicked", SendEvents, p_vout );          \
-    var_AddCallback( newvout, "key-pressed", SendEvents, p_vout )
+    var_AddCallback( newvout, "mouse-clicked", SendEvents, p_vout );
 
 #define DEL_CALLBACKS( newvout, handler ) \
     var_DelCallback( newvout, "fullscreen", SetParentVal, p_vout );           \
     var_DelCallback( newvout, "mouse-x", SendEvents, p_vout );                \
     var_DelCallback( newvout, "mouse-y", SendEvents, p_vout );                \
     var_DelCallback( newvout, "mouse-moved", SendEvents, p_vout );            \
-    var_DelCallback( newvout, "mouse-clicked", SendEvents, p_vout );          \
-    var_DelCallback( newvout, "key-pressed", SendEvents, p_vout )
+    var_DelCallback( newvout, "mouse-clicked", SendEvents, p_vout );
 
 #define ADD_PARENT_CALLBACKS( handler ) \
     var_AddCallback( p_vout, "fullscreen", handler, NULL );                   \
index 70da15cf2e4d08808d19b94dd172e26f59bf51a0..634979c1146d48f7f910a913afbd3450758c08b1 100644 (file)
@@ -2,7 +2,7 @@
  * xcommon.c: Functions common to the X11 and XVideo plugins
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: xcommon.c,v 1.33 2003/10/24 21:27:06 gbazin Exp $
+ * $Id: xcommon.c,v 1.34 2003/10/26 12:46:55 sigmunau Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -34,6 +34,7 @@
 #include <vlc/vlc.h>
 #include <vlc/intf.h>
 #include <vlc/vout.h>
+#include <hotkeys.h>
 
 #ifdef HAVE_MACHINE_PARAM_H
     /* BSD */
@@ -517,92 +518,49 @@ static int ManageVideo( vout_thread_t *p_vout )
         /* Keyboard event */
         else if( xevent.type == KeyPress )
         {
+            vlc_value_t val;
+            val.i_int = 0;
             /* We may have keys like F1 trough F12, ESC ... */
             x_key_symbol = XKeycodeToKeysym( p_vout->p_sys->p_display,
                                              xevent.xkey.keycode, 0 );
             switch( (int)x_key_symbol )
             {
+            case XK_Return:
+            case XK_KP_Enter:
+                val.i_int = KEY_ENTER;
+                break;
             case XK_Escape:
-                if( p_vout->b_fullscreen )
-                {
-                    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
-                }
-                else
-                {
-                    /* the user wants to close the window */
-                    playlist_t * p_playlist =
-                        (playlist_t *)vlc_object_find( p_vout,
-                                                       VLC_OBJECT_PLAYLIST,
-                                                       FIND_ANYWHERE );
-                    if( p_playlist != NULL )
-                    {
-                        playlist_Stop( p_playlist );
-                        vlc_object_release( p_playlist );
-                    }
-                }
+                val.i_int = KEY_ESC;
                 break;
             case XK_Menu:
-                {
-                    intf_thread_t *p_intf;
-                    playlist_t * p_playlist;
-
-                    p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
-                                                      FIND_ANYWHERE );
-                    if( p_intf )
-                    {
-                        p_intf->b_menu_change = 1;
-                        vlc_object_release( p_intf );
-                    }
-
-                    p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
-                                                           FIND_ANYWHERE );
-                    if( p_playlist != NULL )
-                    {
-                        vlc_value_t val;
-                        var_Set( p_playlist, "intf-popupmenu", val );
-                        vlc_object_release( p_playlist );
-                    }
-                }
+                val.i_int = KEY_MENU;
                 break;
             case XK_Left:
-/*                input_Seek( p_vout, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); */
-                val.psz_string = "LEFT";
-                var_Set( p_vout, "key-pressed", val );
+                val.i_int = KEY_LEFT;
                 break;
             case XK_Right:
-/*                input_Seek( p_vout, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); */
-                val.psz_string = "RIGHT";
-                var_Set( p_vout, "key-pressed", val );
+                val.i_int = KEY_RIGHT;
                 break;
             case XK_Up:
-/*                input_Seek( p_vout, 60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); */
-                val.psz_string = "UP";
-                var_Set( p_vout, "key-pressed", val );
+                val.i_int = KEY_UP;
                 break;
             case XK_Down:
-/*                input_Seek( p_vout, -60, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); */
-                val.psz_string = "DOWN";
-                var_Set( p_vout, "key-pressed", val );
-                break;
-            case XK_Return:
-            case XK_KP_Enter:
-                val.psz_string = "ENTER";
-                var_Set( p_vout, "key-pressed", val );
+                val.i_int = KEY_DOWN;
                 break;
             case XK_Home:
-                input_Seek( p_vout, 0, INPUT_SEEK_BYTES | INPUT_SEEK_SET );
+                val.i_int = KEY_HOME;
                 break;
             case XK_End:
-                input_Seek( p_vout, 0, INPUT_SEEK_BYTES | INPUT_SEEK_END );
+                val.i_int = KEY_END;
                 break;
             case XK_Page_Up:
-                input_Seek( p_vout, 10, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+                val.i_int = KEY_PAGEUP;
                 break;
             case XK_Page_Down:
-                input_Seek( p_vout, -10, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
+                val.i_int = KEY_PAGEDOWN;
                 break;
             case XK_space:
-                input_SetStatus( p_vout, INPUT_STATUS_PAUSE );
+                val.i_int = KEY_SPACE;
                 break;
 
             default:
@@ -614,23 +572,34 @@ static int ManageVideo( vout_thread_t *p_vout )
                 if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
                 {
                     /* FIXME: handle stuff here */
-                    switch( i_key )
-                    {
-                    case 'q':
-                    case 'Q':
-                        p_vout->p_vlc->b_die = 1;
-                        break;
-                    case 'f':
-                    case 'F':
-                        p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
-                        break;
-
-                    default:
-                        break;
-                    }
+                    val.i_int = i_key;
                 }
                 break;
             }
+            if ( val.i_int )
+            {
+                if ( xevent.xkey.state & ShiftMask )
+                {
+                    val.i_int |= KEY_MODIFIER_SHIFT;
+                }
+                if ( xevent.xkey.state & ControlMask )
+                {
+                    msg_Dbg( p_vout, "control pressed, key value is %x", val.i_int );
+                    val.i_int |= KEY_MODIFIER_CTRL;
+                }
+                if ( xevent.xkey.state & Mod1Mask )
+                {
+                    val.i_int |= KEY_MODIFIER_ALT;
+                }
+                if ( val.i_int == config_GetInt( p_vout, "fullscreen-key" ) )
+                {
+                    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                }
+                else
+                {
+                    var_Set( p_vout->p_vlc, "key-pressed", val );
+                }
+            }
         }
         /* Mouse click */
         else if( xevent.type == ButtonPress )
index eb91cf416d1443856474002984bf4e3854724e2f..ac5142d45ba144fcfbf124ee6849f2418af14d3d 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.c: main libvlc source
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.c,v 1.98 2003/10/23 16:43:37 sam Exp $
+ * $Id: libvlc.c,v 1.99 2003/10/26 12:46:55 sigmunau Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -564,6 +564,10 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
         p_vlc->pf_memset = memset;
     }
 
+    /*
+     * Initialize hotkey handling
+     */
+    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
     /*
      * Initialize playlist and get commandline files
      */
@@ -608,6 +612,11 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
         free( psz_modules );
     }
 
+    /*
+     * Allways load the hotkeys interface if it exists
+     */
+    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE );
+
     /*
      * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
      */