diff --git a/Makefile.in b/Makefile.in
index 674061d0588f24b9ecafbc2527ebffe182672b3c..caa981ecfeb2b97dfb39b0ca2dba21c6da6dd7e9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -185,6 +185,7 @@ INTERFACE =	src/interface/main.o \
 		src/interface/intf_cmd.o \
 		src/interface/intf_ctrl.o \
 		src/interface/intf_plst.o \
+		src/interface/intf_channels.o \
 		src/interface/intf_console.o
 
 INPUT =		src/input/input_ext-dec.o \
@@ -238,8 +239,7 @@ MISC =		src/misc/mtime.o \
 		src/misc/tests.o \
 		src/misc/rsc_files.o \
 		src/misc/modules.o \
-		src/misc/netutils.o \
-		src/misc/plugins.o
+		src/misc/netutils.o
 
 
 C_OBJ =		$(INTERFACE) \
@@ -314,7 +314,6 @@ PLUGIN_GGI =	plugins/ggi/ggi.o \
 		plugins/ggi/vout_ggi.o
 
 PLUGIN_SDL =	plugins/sdl/sdl.o \
-		plugins/sdl/intf_sdl.o \
 		plugins/sdl/vout_sdl.o \
 		plugins/sdl/aout_sdl.o 
 
@@ -324,10 +323,9 @@ PLUGIN_GLIDE =	plugins/glide/glide.o \
 
 PLUGIN_GNOME =	plugins/gnome/gnome.o \
 		plugins/gnome/intf_gnome.o \
-		plugins/gnome/intf_gnome_callbacks.o \
-		plugins/gnome/intf_gnome_interface.o \
-		plugins/gnome/intf_gnome_support.o \
-		plugins/gnome/vout_gnome.o
+		plugins/gnome/gnome_callbacks.o \
+		plugins/gnome/gnome_interface.o \
+		plugins/gnome/gnome_support.o
 
 PLUGIN_MGA =	plugins/mga/mga.o \
 		plugins/mga/intf_mga.o \
diff --git a/configure b/configure
index a4cae0cde2ba646b58aedf498f76fbaafb7b5983..d33058813e886aa5ef4e5ec6069e8d2f9b1f0cb1 100755
--- a/configure
+++ b/configure
@@ -22,7 +22,7 @@ ac_help="$ac_help
 ac_help="$ac_help
   --disable-optimizations Disable compiler optimizations (default enabled)"
 ac_help="$ac_help
-  --disable-dummy         dummy audio and video support (default enabled)"
+  --enable-dummy          dummy audio and video support (default disabled)"
 ac_help="$ac_help
   --disable-null          Null module (default enabled)"
 ac_help="$ac_help
@@ -34,13 +34,13 @@ ac_help="$ac_help
 ac_help="$ac_help
   --with-ggi[=name]       GGI support (default disabled)"
 ac_help="$ac_help
-  --with-sdl[=name]       SDL support (default disabled)"
+  --with-sdl[=name]       SDL support (default enabled)"
 ac_help="$ac_help
   --with-glide[=name]     Glide (3dfx) support (default disabled)"
 ac_help="$ac_help
-  --enable-gnome          Gnome support (default disabled)"
+  --disable-gnome         Gnome support (default enabled)"
 ac_help="$ac_help
-  --disable-x11           X11 support (default enabled)"
+  --enable-x11            X11 support (default disabled)"
 ac_help="$ac_help
   --enable-alsa           Alsa sound drivers support (Only for linux) (default disabled)"
 
@@ -3419,10 +3419,9 @@ else
 # Check whether --enable-dummy or --disable-dummy was given.
 if test "${enable_dummy+set}" = set; then
   enableval="$enable_dummy"
-  :
+  if test x$enable_dummy = xyes; then PLUGINS=${PLUGINS}"dummy "; fi
 fi
 
-if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
 # Check whether --enable-null or --disable-null was given.
 if test "${enable_null+set}" = set; then
   enableval="$enable_null"
@@ -3473,6 +3472,11 @@ if test "${with_sdl+set}" = set; then
     fi 
 fi
 
+    if test "x$withval" == "x";
+    then
+      PLUGINS=${PLUGINS}"sdl "
+      LIB_SDL="-lSDL"
+    fi
 # Check whether --with-glide or --without-glide was given.
 if test "${with_glide+set}" = set; then
   withval="$with_glide"
@@ -3488,32 +3492,33 @@ fi
 # Check whether --enable-gnome or --disable-gnome was given.
 if test "${enable_gnome+set}" = set; then
   enableval="$enable_gnome"
-  if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi
+  :
 fi
 
+if test x$enable_gnome != xno; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi
 # Check whether --enable-x11 or --disable-x11 was given.
 if test "${enable_x11+set}" = set; then
   enableval="$enable_x11"
-  :
+  if test x$enable_x11 = xyes; then PLUGINS=${PLUGINS}"x11 "; fi
 fi
 
-if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
+
 # Check whether --enable-alsa or --disable-alsa was given.
 if test "${enable_alsa+set}" = set; then
   enableval="$enable_alsa"
   if test x$enable_alsa = xyes; then ac_safe=`echo "sys/asoundlib.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/asoundlib.h""... $ac_c" 1>&6
-echo "configure:3507: checking for sys/asoundlib.h" >&5
+echo "configure:3512: checking for sys/asoundlib.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3512 "configure"
+#line 3517 "configure"
 #include "confdefs.h"
 #include <sys/asoundlib.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3517: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3530,7 +3535,7 @@ fi
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6
-echo "configure:3534: checking for main in -lasound" >&5
+echo "configure:3539: checking for main in -lasound" >&5
 ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3538,14 +3543,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lasound  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3542 "configure"
+#line 3547 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:3549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
diff --git a/configure.in b/configure.in
index bee9b459a6cce414cac8ee3401b48c267b65678f..31d46942d7553d8845bda5d0b11d06aedc84af17 100644
--- a/configure.in
+++ b/configure.in
@@ -138,8 +138,8 @@ dnl default case
 else
 
 AC_ARG_ENABLE(dummy,
-  [  --disable-dummy         dummy audio and video support (default enabled)])
-if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
+  [  --enable-dummy          dummy audio and video support (default disabled)],
+  [if test x$enable_dummy = xyes; then PLUGINS=${PLUGINS}"dummy "; fi])
 AC_ARG_ENABLE(null,
   [  --disable-null          Null module (default enabled)])
 if test x$enable_null != xno; then PLUGINS=${PLUGINS}"null "; fi
@@ -162,7 +162,7 @@ AC_ARG_WITH(ggi,
       LIB_GGI="-lggi"
     fi ])
 AC_ARG_WITH(sdl,
-  [  --with-sdl[=name]       SDL support (default disabled)],
+  [  --with-sdl[=name]       SDL support (default enabled)],
   [ PLUGINS=${PLUGINS}"sdl ";
     if test "x$withval" != "xyes";
     then
@@ -170,6 +170,11 @@ AC_ARG_WITH(sdl,
     else
       LIB_SDL="-lSDL"
     fi ])
+    if test "x$withval" == "x";
+    then
+      PLUGINS=${PLUGINS}"sdl "
+      LIB_SDL="-lSDL"
+    fi
 AC_ARG_WITH(glide,
   [  --with-glide[=name]     Glide (3dfx) support (default disabled)],
   [ PLUGINS=${PLUGINS}"glide ";
@@ -180,11 +185,12 @@ AC_ARG_WITH(glide,
       LIB_GLIDE="-lglide2x"
     fi ])
 AC_ARG_ENABLE(gnome,
-  [  --enable-gnome          Gnome support (default disabled)],
-  [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi])
+  [  --disable-gnome         Gnome support (default enabled)])
+if test x$enable_gnome != xno; then PLUGINS=${PLUGINS}"gnome "; ALIASES=${ALIASES}"gvlc "; fi
 AC_ARG_ENABLE(x11,
-  [  --disable-x11           X11 support (default enabled)])
-if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
+  [  --enable-x11            X11 support (default disabled)],
+  [if test x$enable_x11 = xyes; then PLUGINS=${PLUGINS}"x11 "; fi])
+
 AC_ARG_ENABLE(alsa,
   [  --enable-alsa           Alsa sound drivers support (Only for linux) (default disabled)],
   [if test x$enable_alsa = xyes; then AC_CHECK_HEADER(sys/asoundlib.h, AC_CHECK_LIB(asound, main, have_alsa="true", have_alsa="false"),have_alsa="false") if test $have_alsa = true; then PLUGINS=${PLUGINS}"alsa "; fi; fi])
diff --git a/include/config.h.in b/include/config.h.in
index d1da688834ce7e57e489b22dec0ea1e52d0d6d81..a9bcbf0cba00f61452faf1031083514fcd8f6afd 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -128,6 +128,9 @@
  * Interface configuration
  *****************************************************************************/
 
+/* Environment variable containing the display method */
+#define INTF_METHOD_VAR                 "vlc_intf"
+
 /* Environment variable used to store startup script name and default value */
 #define INTF_INIT_SCRIPT_VAR            "vlcrc"
 #define INTF_INIT_SCRIPT_DEFAULT        ".vlcrc"
diff --git a/include/interface.h b/include/interface.h
index 2354e6db127fb8e2033f5297e6a0926d52407dd8..32cc4b1cc699689278b59cf5be379259fce31de0 100644
--- a/include/interface.h
+++ b/include/interface.h
@@ -43,11 +43,6 @@
  * This structe describes all interface-specific data of the main (interface)
  * thread.
  *****************************************************************************/
-typedef int   ( intf_sys_create_t )   ( p_intf_thread_t p_intf );
-typedef void  ( intf_sys_destroy_t )  ( p_intf_thread_t p_intf );
-typedef void  ( intf_sys_manage_t )   ( p_intf_thread_t p_intf );
-
-
 typedef struct _keyparam
 {
     int key;
@@ -72,10 +67,14 @@ typedef struct intf_thread_s
     p_intf_sys_t        p_sys;                           /* system interface */
     p_intf_key          p_keys;
     
-    /* Plugin */
-    intf_sys_create_t *     p_sys_create;         /* create interface thread */
-    intf_sys_manage_t *     p_sys_manage;                       /* main loop */
-    intf_sys_destroy_t *    p_sys_destroy;              /* destroy interface */
+    /* Plugin used and shortcuts to access its capabilities */
+    struct module_s *   p_module;
+    int              ( *pf_open )   ( struct intf_thread_s * );
+    void             ( *pf_close )  ( struct intf_thread_s * );
+    void             ( *pf_run )    ( struct intf_thread_s * );
+
+    /* Interface callback */
+    void             ( *pf_manage ) ( struct intf_thread_s * );
 
     /* XXX: Channels array - new API */
   //p_intf_channel_t *  p_channel[INTF_MAX_CHANNELS];/* channel descriptions */
@@ -84,24 +83,24 @@ typedef struct intf_thread_s
     p_intf_channel_t    p_channel;                /* description of channels */
 
     /* Main threads - NULL if not active */
-    p_vout_thread_t     p_vout;
     p_input_thread_t    p_input;
 
     /* Specific functions */
     keyparm (*p_intf_get_key)(struct intf_thread_s *p_intf, int r_key) ;
+
+    /* XXX: new message passing stuff will go here */
+    vlc_mutex_t         change_lock;
+    boolean_t           b_menu_change;
+    boolean_t           b_menu;
     
-    /* Warning messages level */
-    int                 i_warning_level;
 } intf_thread_t;
 
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
 intf_thread_t * intf_Create             ( void );
-void            intf_Run                ( intf_thread_t * p_intf );
 void            intf_Destroy            ( intf_thread_t * p_intf );
 
-int             intf_SelectChannel      ( intf_thread_t * p_intf, int i_channel );
 int             intf_ProcessKey         ( intf_thread_t * p_intf, int i_key );
 
 void intf_AssignKey( intf_thread_t *p_intf, int r_key, int f_key, int param);
diff --git a/include/main.h b/include/main.h
index af1d327052213d79b3aa89994e9a04d719398694..9e52f66b1e18871b45ffcc4e1685b7d3ef69dd58 100644
--- a/include/main.h
+++ b/include/main.h
@@ -39,7 +39,9 @@ typedef struct
     char **                ppsz_argv;              /* command line arguments */
     char **                ppsz_env;                /* environment variables */
     char *                 psz_arg0;         /* program name (whithout path) */
+
     int                    i_cpu_capabilities;             /* CPU extensions */
+    int                    i_warning_level;        /* warning messages level */
 
     /* Generic settings */
     boolean_t              b_audio;             /* is audio output allowed ? */
@@ -48,13 +50,13 @@ typedef struct
     boolean_t              b_dvd;                              /* DVD mode ? */
 
     /* Unique threads */
+    p_vout_thread_t        p_vout;                    /* video output thread */
     p_aout_thread_t        p_aout;                    /* audio output thread */
     p_intf_thread_t        p_intf;                  /* main interface thread */
 
     /* Shared data - these structures are accessed directly from p_main by
      * several modules */
-    struct module_bank_s * p_module_bank;                     /* module bank */
-    p_plugin_bank_t        p_bank;                            /* plugin bank */
+    struct module_bank_s * p_bank;                            /* module bank */
     p_playlist_t           p_playlist;                           /* playlist */
     p_intf_msg_t           p_msg;                 /* messages interface data */
     p_input_vlan_t         p_vlan;                      /* vlan library data */
diff --git a/include/modules.h b/include/modules.h
index ee7d6024bdfebf6c782e44606cf052817415a58e..9dfa8c10fdf7ffe3ed1db4a17f44624e3df9ae82 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -65,6 +65,14 @@ typedef struct function_list_s
 
     union
     {
+        /* Interface plugin */
+        struct
+        {
+            int  ( * pf_open ) ( struct intf_thread_s * );
+            void ( * pf_close )( struct intf_thread_s * );
+            void ( * pf_run )  ( struct intf_thread_s * );
+        } intf;
+
         /* Input plugin */
         struct
         {
@@ -98,6 +106,19 @@ typedef struct function_list_s
             void ( * pf_close )      ( struct aout_thread_s * );
         } aout;
 
+        /* Video output plugin */
+        struct
+        {
+            int  ( * pf_create )     ( struct vout_thread_s * );
+            int  ( * pf_init )       ( struct vout_thread_s * );
+            void ( * pf_end )        ( struct vout_thread_s * );
+            void ( * pf_destroy )    ( struct vout_thread_s * );
+            int  ( * pf_manage )     ( struct vout_thread_s * );
+            void ( * pf_display )    ( struct vout_thread_s * );
+            void ( * pf_setpalette ) ( struct vout_thread_s *, u16 *red,
+                                       u16 *green, u16 *blue, u16 *transp );
+        } vout;
+
         /* Motion compensation plugin */
         struct
         {
diff --git a/include/plugins.h b/include/plugins.h
deleted file mode 100644
index de1c34a923d811525b236b24fd898199644a22d1..0000000000000000000000000000000000000000
--- a/include/plugins.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*****************************************************************************
- * plugins.h : Dynamic plugin management functions
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * 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.
- *****************************************************************************/
-
-#ifdef SYS_BEOS
-typedef int plugin_id_t;
-#define GET_PLUGIN( p_func, plugin_id, psz_name ) \
-    get_image_symbol( plugin_id, psz_name, B_SYMBOL_TYPE_TEXT, &p_func );
-#else
-typedef void *plugin_id_t;
-#define GET_PLUGIN( p_func, plugin_id, psz_name ) \
-    p_func = dlsym( plugin_id, psz_name );
-#endif
-
-typedef struct plugin_info_s
-{
-    plugin_id_t plugin_id;
-
-    char *      psz_filename;
-    char *      psz_name;
-    char *      psz_version;
-    char *      psz_author;
-
-    void *      aout_GetPlugin;
-    void *      vout_GetPlugin;
-    void *      intf_GetPlugin;
-    void *      yuv_GetPlugin;
-
-    int         i_score;
-} plugin_info_t;
-
-typedef struct plugin_bank_s
-{
-    int               i_plugin_count;
-    plugin_info_t *   p_info[ MAX_PLUGIN_COUNT ];
-} plugin_bank_t;
-
-plugin_bank_t *  bank_Create       ( void );
-void             bank_Init         ( plugin_bank_t * p_bank );
-void             bank_Destroy      ( plugin_bank_t * p_bank );
-
diff --git a/include/video_output.h b/include/video_output.h
index 51b1b9c063aac5f8c281b926afd32c45184b6ef4..a34bd447e2ef3b5bf69b95056e5e6e6e3f3402be 100644
--- a/include/video_output.h
+++ b/include/video_output.h
@@ -112,18 +112,6 @@ typedef struct vout_buffer_s
  * is represented by a video output thread, and described using the following
  * structure.
  *****************************************************************************/
-typedef int  (vout_sys_create_t)    ( p_vout_thread_t p_vout,
-                                      char *psz_display,
-                                      int i_root_window, void *p_data );
-typedef int  (vout_sys_init_t)      ( p_vout_thread_t p_vout );
-typedef void (vout_sys_end_t)       ( p_vout_thread_t p_vout );
-typedef void (vout_sys_destroy_t)   ( p_vout_thread_t p_vout );
-typedef int  (vout_sys_manage_t)    ( p_vout_thread_t p_vout );
-typedef void (vout_sys_display_t)   ( p_vout_thread_t p_vout );
-
-typedef void (vout_set_palette_t)   ( p_vout_thread_t p_vout, u16 *red,
-                                      u16 *green, u16 *blue, u16 *transp );
-
 typedef struct vout_thread_s
 {
     /* Thread properties and lock */
@@ -165,15 +153,16 @@ typedef struct vout_thread_s
     u32                 i_gray_pixel;                                /* gray */
     u32                 i_blue_pixel;                                /* blue */
 
-    /* Plugins */
-    vout_sys_create_t *     p_sys_create;          /* allocate output method */
-    vout_sys_init_t *       p_sys_init;          /* initialize output method */
-    vout_sys_end_t *        p_sys_end;            /* terminate output method */
-    vout_sys_destroy_t *    p_sys_destroy;          /* destroy output method */
-    vout_sys_manage_t *     p_sys_manage;                   /* handle events */
-    vout_sys_display_t *    p_sys_display;         /* display rendered image */
-
-    vout_set_palette_t *    p_set_palette;               /* set 8bpp palette */
+    /* Plugin used and shortcuts to access its capabilities */
+    struct module_s *   p_module;
+    int              ( *pf_create )     ( struct vout_thread_s * );
+    int              ( *pf_init )       ( struct vout_thread_s * );
+    void             ( *pf_end )        ( struct vout_thread_s * );
+    void             ( *pf_destroy )    ( struct vout_thread_s * );
+    int              ( *pf_manage )     ( struct vout_thread_s * );
+    void             ( *pf_display )    ( struct vout_thread_s * );
+    void             ( *pf_setpalette ) ( struct vout_thread_s *, u16 *red,
+                                          u16 *green, u16 *blue, u16 *transp );
 
     /* Pictures and rendering properties */
     boolean_t           b_grayscale;           /* color or grayscale display */
@@ -243,17 +232,16 @@ typedef struct vout_thread_s
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-vout_thread_t * vout_CreateThread       ( char *psz_display, int i_root_window,
-                                          int i_width, int i_height, int *pi_status,
-                                          int i_method, void *p_data );
-void            vout_DestroyThread      ( vout_thread_t *p_vout, int *pi_status );
-picture_t *     vout_CreatePicture      ( vout_thread_t *p_vout, int i_type,
-                                          int i_width, int i_height );
-void            vout_DestroyPicture     ( vout_thread_t *p_vout, picture_t *p_pic );
-void            vout_DisplayPicture     ( vout_thread_t *p_vout, picture_t *p_pic );
-void            vout_DatePicture        ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date );
-void            vout_LinkPicture        ( vout_thread_t *p_vout, picture_t *p_pic );
-void            vout_UnlinkPicture      ( vout_thread_t *p_vout, picture_t *p_pic );
+vout_thread_t * vout_CreateThread   ( int *pi_status );
+void            vout_DestroyThread  ( vout_thread_t *p_vout, int *pi_status );
+picture_t *     vout_CreatePicture  ( vout_thread_t *p_vout, int i_type,
+                                      int i_width, int i_height );
+void            vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic );
+void            vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic );
+void            vout_DatePicture    ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date );
+void            vout_LinkPicture    ( vout_thread_t *p_vout, picture_t *p_pic );
+void            vout_UnlinkPicture  ( vout_thread_t *p_vout, picture_t *p_pic );
+
 subpicture_t *  vout_CreateSubPicture   ( vout_thread_t *p_vout, int i_type, int i_size );
 void            vout_DestroySubPicture  ( vout_thread_t *p_vout, subpicture_t *p_subpic );
 void            vout_DisplaySubPicture  ( vout_thread_t *p_vout, subpicture_t *p_subpic );
diff --git a/plugins/gnome/gnome.c b/plugins/gnome/gnome.c
index 02d9384179a78e6b16a32046c6a55b28d55b2bff..533dc3271cb090ef7a5e40e9507168e5d6e7f43f 100644
--- a/plugins/gnome/gnome.c
+++ b/plugins/gnome/gnome.c
@@ -3,8 +3,8 @@
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
  *
- * Authors:
- *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *      
  * 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
@@ -20,6 +20,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define MODULE_NAME gnome
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
@@ -27,109 +29,86 @@
 
 #include <stdlib.h>                                      /* malloc(), free() */
 
-#include <X11/Xlib.h>
-
 #include "config.h"
 #include "common.h"                                     /* boolean_t, byte_t */
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"
-#include "plugins.h"
 
 #include "interface.h"
-#include "audio_output.h"
 #include "video.h"
 #include "video_output.h"
 
-#include "main.h"
+#include "modules.h"
+#include "modules_inner.h"
 
 /*****************************************************************************
- * Exported prototypes
+ * Building configuration tree
  *****************************************************************************/
-static void vout_GetPlugin( p_vout_thread_t p_vout );
-static void intf_GetPlugin( p_intf_thread_t p_intf );
-
-/* Video output */
-int     vout_GnomeCreate       ( vout_thread_t *p_vout, char *psz_display,
-                                 int i_root_window, void *p_data );
-int     vout_GnomeInit         ( p_vout_thread_t p_vout );
-void    vout_GnomeEnd          ( p_vout_thread_t p_vout );
-void    vout_GnomeDestroy      ( p_vout_thread_t p_vout );
-int     vout_GnomeManage       ( p_vout_thread_t p_vout );
-void    vout_GnomeDisplay      ( p_vout_thread_t p_vout );
-void    vout_GnomeSetPalette   ( p_vout_thread_t p_vout, u16 *red,
-                                 u16 *green, u16 *blue, u16 *transp );
-
-/* Interface */
-int     intf_GnomeCreate       ( p_intf_thread_t p_intf );
-void    intf_GnomeDestroy      ( p_intf_thread_t p_intf );
-void    intf_GnomeManage       ( p_intf_thread_t p_intf );
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for Gnome module" )
+    ADD_COMMENT( "For now, the Gnome module cannot be configured" )
+MODULE_CONFIG_END
 
 /*****************************************************************************
- * GetConfig: get the plugin structure and configuration
+ * Capabilities defined in the other files.
+ ******************************************************************************/
+extern void intf_getfunctions( function_list_t * p_function_list );
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
  *****************************************************************************/
-plugin_info_t * GetConfig( void )
+int InitModule( module_t * p_module )
 {
-    Display *p_display;
-    plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
-
-    p_info->psz_name    = "Gnome";
-    p_info->psz_version = VERSION;
-    p_info->psz_author  = "the VideoLAN team <vlc@videolan.org>";
-
-    p_info->aout_GetPlugin = NULL;
-    p_info->vout_GetPlugin = vout_GetPlugin;
-    p_info->intf_GetPlugin = intf_GetPlugin;
-    p_info->yuv_GetPlugin  = NULL;
-
-    /* Check that we can open the X display */
-    if( (p_display = XOpenDisplay( XDisplayName(
-                         main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) ) ))
-        == NULL )
-    {
-        p_info->i_score = 0;
-    }
-    else
-    {
-        XCloseDisplay( p_display );
-        p_info->i_score = 0x200;
-    }
+    p_module->psz_name = MODULE_STRING;
+    p_module->psz_longname = "Gnome interface module";
+    p_module->psz_version = VERSION;
 
-    if( TestProgram( "gvlc" ) )
-    {
-        p_info->i_score += 0x180;
-    }
+    p_module->i_capabilities = MODULE_CAPABILITY_NULL
+                                | MODULE_CAPABILITY_INTF;
 
-    /* If this plugin was requested, score it higher */
-    if( TestMethod( VOUT_METHOD_VAR, "gnome" ) )
+    return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+    p_module->p_functions = malloc( sizeof( module_functions_t ) );
+    if( p_module->p_functions == NULL )
     {
-        p_info->i_score += 0x200;
+        return( -1 );
     }
 
-    return( p_info );
+    intf_getfunctions( &p_module->p_functions->intf );
+
+    p_module->p_config = p_config;
+
+    return( 0 );
 }
 
 /*****************************************************************************
- * Following functions are only called through the p_info structure
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
  *****************************************************************************/
-
-static void vout_GetPlugin( p_vout_thread_t p_vout )
+int DeactivateModule( module_t * p_module )
 {
-    p_vout->p_sys_create  = vout_GnomeCreate;
-    p_vout->p_sys_init    = vout_GnomeInit;
-    p_vout->p_sys_end     = vout_GnomeEnd;
-    p_vout->p_sys_destroy = vout_GnomeDestroy;
-    p_vout->p_sys_manage  = vout_GnomeManage;
-    p_vout->p_sys_display = vout_GnomeDisplay;
-
-    /* optional functions */
-    p_vout->p_set_palette = vout_GnomeSetPalette;
-}
+    free( p_module->p_functions );
 
-static void intf_GetPlugin( p_intf_thread_t p_intf )
-{
-    p_intf->p_sys_create  = intf_GnomeCreate;
-    p_intf->p_sys_destroy = intf_GnomeDestroy;
-    p_intf->p_sys_manage  = intf_GnomeManage;
+    return( 0 );
 }
 
diff --git a/plugins/gnome/intf_gnome_callbacks.c b/plugins/gnome/gnome_callbacks.c
similarity index 60%
rename from plugins/gnome/intf_gnome_callbacks.c
rename to plugins/gnome/gnome_callbacks.c
index d01088c80261647b8e684a498485aeb733bb317b..36c299cf799e601b671abbb231b6c437cb9c8a98 100644
--- a/plugins/gnome/intf_gnome_callbacks.c
+++ b/plugins/gnome/gnome_callbacks.c
@@ -3,18 +3,24 @@
 #include "config.h"
 #include "common.h"
 #include "threads.h"
+#include "mtime.h"
 
 #include <gnome.h>
 
-#include "intf_gnome_thread.h"
-#include "intf_gnome_callbacks.h"
-#include "intf_gnome_interface.h"
-#include "intf_gnome_support.h"
+#include "stream_control.h"
+#include "input_ext-intf.h"
+
+#include "interface.h"
+
+#include "gnome_sys.h"
+#include "gnome_callbacks.h"
+#include "gnome_interface.h"
+#include "gnome_support.h"
 
 #define GET_GNOME_STRUCT( item, parent ) \
 gtk_object_get_data( \
     GTK_OBJECT( lookup_widget(GTK_WIDGET(item), parent) ), \
-    "p_gnome" );
+    "p_intf" );
 
 void
 on_modules_activate                    (GtkMenuItem     *menuitem,
@@ -28,11 +34,11 @@ void
 on_exit_activate                       (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" );
 
-    p_gnome->b_die = 1;
+    p_intf->b_die = 1;
 }
 
 
@@ -64,15 +70,15 @@ void
 on_about_activate                      (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" );
 
-    if( !GTK_IS_WIDGET( p_gnome->p_about ) )
+    if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
     {
-        p_gnome->p_about = create_intf_about ();
+        p_intf->p_sys->p_about = create_intf_about ();
     }
-    gtk_widget_show( p_gnome->p_about );
+    gtk_widget_show( p_intf->p_sys->p_about );
 }
 
 
@@ -80,6 +86,9 @@ void
 on_stop_clicked                        (GtkButton       *button,
                                         gpointer         user_data)
 {
+    intf_thread_t *p_intf;
+
+    p_intf = GET_GNOME_STRUCT( button, "intf_window" );
 
 }
 
@@ -88,32 +97,32 @@ void
 on_control_activate                    (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" );
 
     /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
 
-    if( p_gnome->b_window )
+    if( p_intf->p_sys->b_window )
     {
-        gtk_widget_hide( p_gnome->p_window );
-        p_gnome->b_window = 0;
+        gtk_widget_hide( p_intf->p_sys->p_window );
+        p_intf->p_sys->b_window = 0;
     }
     else
     {
-        if( !GTK_IS_WIDGET( p_gnome->p_window ) )
+        if( !GTK_IS_WIDGET( p_intf->p_sys->p_window ) )
         {
-            p_gnome->p_window = create_intf_window ();
+            p_intf->p_sys->p_window = create_intf_window ();
         }
-        gtk_widget_show( p_gnome->p_window );
-        gtk_object_set_data( GTK_OBJECT(p_gnome->p_window),
-                             "p_gnome", p_gnome );
-        p_gnome->b_window = 1;
+        gtk_widget_show( p_intf->p_sys->p_window );
+        gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
+                             "p_intf", p_intf );
+        p_intf->p_sys->b_window = 1;
     }
 
     /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    vlc_mutex_unlock( &p_intf->p_sys->change_lock );
 }
 
 
@@ -121,64 +130,64 @@ void
 on_playlist_activate                   (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_window" );
 
     /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
 
-    if( p_gnome->b_playlist )
+    if( p_intf->p_sys->b_playlist )
     {
-        gtk_widget_hide( p_gnome->p_playlist );
-        p_gnome->b_playlist = 0;
+        gtk_widget_hide( p_intf->p_sys->p_playlist );
+        p_intf->p_sys->b_playlist = 0;
     }
     else
     {
-        if( !GTK_IS_WIDGET( p_gnome->p_playlist ) )
+        if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
         {
-            p_gnome->p_playlist = create_intf_playlist ();
+            p_intf->p_sys->p_playlist = create_intf_playlist ();
         }
-        gtk_widget_show( p_gnome->p_playlist );
-        gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist),
-                             "p_gnome", p_gnome );
-        p_gnome->b_playlist = 1;
+        gtk_widget_show( p_intf->p_sys->p_playlist );
+        gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_playlist),
+                             "p_intf", p_intf );
+        p_intf->p_sys->b_playlist = 1;
     }
 
     /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    vlc_mutex_unlock( &p_intf->p_sys->change_lock );
 }
 
 void
 on_popup_control_activate              (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
     /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
 
-    if( p_gnome->b_window )
+    if( p_intf->p_sys->b_window )
     {
-        gtk_widget_hide( p_gnome->p_window );
-        p_gnome->b_window = 0;
+        gtk_widget_hide( p_intf->p_sys->p_window );
+        p_intf->p_sys->b_window = 0;
     }
     else
     {
-        if( !GTK_IS_WIDGET( p_gnome->p_window ) )
+        if( !GTK_IS_WIDGET( p_intf->p_sys->p_window ) )
         {
-            p_gnome->p_window = create_intf_window ();
+            p_intf->p_sys->p_window = create_intf_window ();
         }
-        gtk_widget_show( p_gnome->p_window );
-        gtk_object_set_data( GTK_OBJECT(p_gnome->p_window),
-                             "p_gnome", p_gnome );
-        p_gnome->b_window = 1;
+        gtk_widget_show( p_intf->p_sys->p_window );
+        gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
+                             "p_intf", p_intf );
+        p_intf->p_sys->b_window = 1;
     }
 
     /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    vlc_mutex_unlock( &p_intf->p_sys->change_lock );
 }
 
 
@@ -186,32 +195,32 @@ void
 on_popup_playlist_activate             (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
     /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    vlc_mutex_lock( &p_intf->p_sys->change_lock );
 
-    if( p_gnome->b_playlist )
+    if( p_intf->p_sys->b_playlist )
     {
-        gtk_widget_hide( p_gnome->p_playlist );
-        p_gnome->b_playlist = 0;
+        gtk_widget_hide( p_intf->p_sys->p_playlist );
+        p_intf->p_sys->b_playlist = 0;
     }
     else
     {
-        if( !GTK_IS_WIDGET( p_gnome->p_playlist ) )
+        if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
         {
-            p_gnome->p_playlist = create_intf_playlist ();
+            p_intf->p_sys->p_playlist = create_intf_playlist ();
         }
-        gtk_widget_show( p_gnome->p_playlist );
-        gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist),
-                             "p_gnome", p_gnome );
-        p_gnome->b_playlist = 1;
+        gtk_widget_show( p_intf->p_sys->p_playlist );
+        gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_playlist),
+                             "p_intf", p_intf );
+        p_intf->p_sys->b_playlist = 1;
     }
 
     /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    vlc_mutex_unlock( &p_intf->p_sys->change_lock );
 }
 
 
@@ -220,11 +229,11 @@ void
 on_popup_exit_activate                 (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
-    p_gnome->b_die = 1;
+    p_intf->b_die = 1;
 }
 
 
@@ -232,15 +241,15 @@ void
 on_popup_about_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
-    if( !GTK_IS_WIDGET( p_gnome->p_about ) )
+    if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
     {
-        p_gnome->p_about = create_intf_about ();
+        p_intf->p_sys->p_about = create_intf_about ();
     }
-    gtk_widget_show( p_gnome->p_about );
+    gtk_widget_show( p_intf->p_sys->p_about );
 }
 
 
@@ -248,7 +257,14 @@ void
 on_intf_window_destroy                 (GtkObject       *object,
                                         gpointer         user_data)
 {
-   fprintf( stderr, "interface window destroyed !\n" );
+    intf_thread_t *p_intf;
+
+    p_intf = GET_GNOME_STRUCT( object, "intf_window" );
+
+    /* FIXME don't destroy the window, just hide it */
+    p_intf->p_sys->p_window = NULL;
+
+    p_intf->b_die = 1;
 }
 
 
@@ -256,7 +272,7 @@ void
 on_intf_playlist_destroy               (GtkObject       *object,
                                         gpointer         user_data)
 {
-   fprintf( stderr, "playlist window destroyed !\n" );
+   ;
 }
 
 
@@ -377,14 +393,11 @@ void
 on_popup_play_activate                 (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
-    vlc_mutex_lock( &p_gnome->change_lock );
-    p_gnome->b_activity_changed = 1;
-    p_gnome->b_activity = 1;
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    input_Play( p_intf->p_input );
 }
 
 
@@ -400,14 +413,11 @@ void
 on_play_clicked                        (GtkButton       *button,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( button, "intf_window" );
 
-    vlc_mutex_lock( &p_gnome->change_lock );
-    p_gnome->b_activity_changed = 1;
-    p_gnome->b_activity = 1;
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    input_Play( p_intf->p_input );
 }
 
 
@@ -442,11 +452,11 @@ on_open_clicked                        (GtkButton       *button,
         }
     };
 
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( button, "intf_window" );
 
-    gnome_app_insert_menus (GNOME_APP (p_gnome->p_window),
+    gnome_app_insert_menus (GNOME_APP (p_intf->p_sys->p_window),
                               "_View/Channel/None",
                               test_uiinfo);
 }
@@ -456,14 +466,11 @@ void
 on_pause_clicked                       (GtkButton       *button,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+    p_intf = GET_GNOME_STRUCT( button, "intf_window" );
 
-    vlc_mutex_lock( &p_gnome->change_lock );
-    p_gnome->b_activity_changed = 1;
-    p_gnome->b_activity = 0;
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    input_Pause( p_intf->p_input );
 }
 
 
@@ -471,14 +478,11 @@ void
 on_popup_pause_activate                (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-    gnome_thread_t *p_gnome;
+    intf_thread_t *p_intf;
 
-    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+    p_intf = GET_GNOME_STRUCT( menuitem, "intf_popup" );
 
-    vlc_mutex_lock( &p_gnome->change_lock );
-    p_gnome->b_activity_changed = 1;
-    p_gnome->b_activity = 0;
-    vlc_mutex_unlock( &p_gnome->change_lock );
+    input_Pause( p_intf->p_input );
 }
 
 
diff --git a/plugins/gnome/intf_gnome_callbacks.h b/plugins/gnome/gnome_callbacks.h
similarity index 100%
rename from plugins/gnome/intf_gnome_callbacks.h
rename to plugins/gnome/gnome_callbacks.h
diff --git a/plugins/gnome/intf_gnome_interface.c b/plugins/gnome/gnome_interface.c
similarity index 99%
rename from plugins/gnome/intf_gnome_interface.c
rename to plugins/gnome/gnome_interface.c
index a9c60d79118a4cdce0febbc1e610580acdca36ea..0b3e2db0a64868c7b4567b01a04d48dbcab7883c 100644
--- a/plugins/gnome/intf_gnome_interface.c
+++ b/plugins/gnome/gnome_interface.c
@@ -13,9 +13,9 @@
 
 #include <gnome.h>
 
-#include "intf_gnome_callbacks.h"
-#include "intf_gnome_interface.h"
-#include "intf_gnome_support.h"
+#include "gnome_callbacks.h"
+#include "gnome_interface.h"
+#include "gnome_support.h"
 
 static GnomeUIInfo file_menu_menu_uiinfo[] =
 {
diff --git a/plugins/gnome/intf_gnome_interface.h b/plugins/gnome/gnome_interface.h
similarity index 100%
rename from plugins/gnome/intf_gnome_interface.h
rename to plugins/gnome/gnome_interface.h
diff --git a/plugins/gnome/intf_gnome_support.c b/plugins/gnome/gnome_support.c
similarity index 99%
rename from plugins/gnome/intf_gnome_support.c
rename to plugins/gnome/gnome_support.c
index d13ea74000579d2b6eda943cd33fb75ff7db26f5..f65d7698bf8e90d545ff76f2045bc8b444dc1584 100644
--- a/plugins/gnome/intf_gnome_support.c
+++ b/plugins/gnome/gnome_support.c
@@ -13,7 +13,7 @@
 
 #include <gnome.h>
 
-#include "intf_gnome_support.h"
+#include "gnome_support.h"
 
 /* This is an internally used function to create pixmaps. */
 static GtkWidget* create_dummy_pixmap  (GtkWidget       *widget,
diff --git a/plugins/gnome/intf_gnome_support.h b/plugins/gnome/gnome_support.h
similarity index 100%
rename from plugins/gnome/intf_gnome_support.h
rename to plugins/gnome/gnome_support.h
diff --git a/plugins/gnome/intf_gnome_thread.h b/plugins/gnome/gnome_sys.h
similarity index 78%
rename from plugins/gnome/intf_gnome_thread.h
rename to plugins/gnome/gnome_sys.h
index 293cd7ec3d635704b4096e91bfc2109505e906e7..de74cc197493a3191d11bdc27de414f7367bb0c5 100644
--- a/plugins/gnome/intf_gnome_thread.h
+++ b/plugins/gnome/gnome_sys.h
@@ -1,7 +1,8 @@
 /*****************************************************************************
- * intf_gnome_thread.h: Gnome thread
+ * gnome_sys.h: private Gnome interface description
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: gnome_sys.h,v 1.1 2001/02/11 01:15:10 sam Exp $
  *
  * Authors:
  *
@@ -17,18 +18,14 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
 /*****************************************************************************
  * intf_sys_t: description and status of Gnome interface
  *****************************************************************************/
-typedef struct gnome_thread_s
+typedef struct intf_sys_s
 {
-    vlc_thread_t        thread_id;                /* id for thread functions */
-    boolean_t           b_die;                                 /* `die' flag */
-    boolean_t           b_error;                             /* `error' flag */
-
     /* special actions */
     vlc_mutex_t         change_lock;                      /* the change lock */
 
@@ -43,16 +40,18 @@ typedef struct gnome_thread_s
     boolean_t           b_playlist_changed;    /* playlist display toggled ? */
     boolean_t           b_playlist;                    /* display playlist ? */
 
+    /* intf_Manage callback timeout */
+    int                 i_timeout;
+
     /* windows and widgets */
     GtkWidget *         p_window;                             /* main window */
     GtkWidget *         p_popup;                               /* popup menu */
     GtkWidget *         p_playlist;                              /* playlist */
     GtkWidget *         p_about;                             /* about window */
 
-} gnome_thread_t;
+    /* XXX: ugly kludge */
+    void             ( *pf_gtk_callback ) ( void );
+    void             ( *pf_gdk_callback ) ( void );
 
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-void        GnomeThread              ( gnome_thread_t *p_gnome );
+} intf_sys_t;
 
diff --git a/plugins/gnome/intf_gnome.c b/plugins/gnome/intf_gnome.c
index 0f558ba2dad840155ec8ec219c6397661b6fbc92..a4c8bb43d246179ae9a31c0fcb96b3354f39068a 100644
--- a/plugins/gnome/intf_gnome.c
+++ b/plugins/gnome/intf_gnome.c
@@ -2,7 +2,7 @@
  * intf_gnome.c: Gnome interface
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.c,v 1.7 2001/01/15 06:18:22 sam Exp $
+ * $Id: intf_gnome.c,v 1.8 2001/02/11 01:15:10 sam Exp $
  *
  * Authors:
  *
@@ -29,641 +29,218 @@
 #include <errno.h>                                                 /* ENOMEM */
 #include <stdlib.h>                                                /* free() */
 #include <string.h>                                            /* strerror() */
+#include <stdio.h>
+
+#include "glib.h"
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/keysym.h>
 
+#include <gnome.h>
+
 #include "config.h"
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
+#include "tests.h"
+#include "modules.h"
 
 #include "stream_control.h"
 #include "input_ext-intf.h"
 
-#include "video.h"
-#include "video_output.h"
-
-#include "audio_output.h" /* needed for mute */
-
 #include "intf_msg.h"
 #include "interface.h"
 
-#include "main.h"
+#include "gnome_sys.h"
+#include "gnome_interface.h"
+#include "gnome_support.h"
 
-#include <stdio.h>
-
-#include <gnome.h>
-
-#include "intf_gnome_thread.h"
-#include "intf_gnome.h"
-#include "intf_gnome_interface.h"
-#include "intf_gnome_support.h"
+#include "main.h"
 
 /*****************************************************************************
- * intf_GnomeCreate: initialize and create window
+ * Local prototypes.
  *****************************************************************************/
-int intf_GnomeCreate( intf_thread_t *p_intf )
-{
-    char       *psz_display;
+static int  intf_Probe     ( probedata_t *p_data );
+static int  intf_Open      ( intf_thread_t *p_intf );
+static void intf_Close     ( intf_thread_t *p_intf );
+static void intf_Run       ( intf_thread_t *p_intf );
 
-    /* Allocate instance and initialize some members */
-    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
-    if( p_intf->p_sys == NULL )
-    {
-        intf_ErrMsg("error: %s", strerror(ENOMEM));
-        return( 1 );
-    }
-
-    p_intf->p_sys->p_gnome = malloc( sizeof( gnome_thread_t ) );
-    if( p_intf->p_sys->p_gnome == NULL )
-    {
-        intf_ErrMsg("error: %s", strerror(ENOMEM));
-        free( p_intf->p_sys );
-        return( 1 );
-    }
-
-    /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
-    psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
-    p_intf->p_sys->p_display = XOpenDisplay( psz_display );
-    if( !p_intf->p_sys->p_display )                                 /* error */
-    {
-        intf_ErrMsg("error: can't open display %s", psz_display );
-        free( p_intf->p_sys->p_gnome );
-        free( p_intf->p_sys );
-        return( 1 );
-    }
-    p_intf->p_sys->i_screen = DefaultScreen( p_intf->p_sys->p_display );
-
-    /* Spawn base window - this window will include the video output window */
-    if( GnomeCreateWindow( p_intf ) )
-    {
-        intf_ErrMsg( "error: can't create output window" );
-        XCloseDisplay( p_intf->p_sys->p_display );
-        free( p_intf->p_sys->p_gnome );
-        free( p_intf->p_sys );
-        return( 1 );
-    }
-
-    /* Spawn video output thread */
-    if( p_main->b_video )
-    {
-        p_intf->p_vout = vout_CreateThread( psz_display, p_intf->p_sys->window,
-                                            p_intf->p_sys->i_width,
-                                            p_intf->p_sys->i_height, NULL, 0,
-                                            (void *)&p_intf->p_sys->colormap );
-
-        if( p_intf->p_vout == NULL )                                /* error */
-        {
-            intf_ErrMsg("error: can't create video output thread" );
-            GnomeDestroyWindow( p_intf );
-            XCloseDisplay( p_intf->p_sys->p_display );
-            free( p_intf->p_sys->p_gnome );
-            free( p_intf->p_sys );
-            return( 1 );
-        }
-    }
-
-    /* Spawn Gnome thread */
-    p_intf->p_sys->p_gnome->b_die = 0;
-    p_intf->p_sys->p_gnome->b_error = 0;
-    
-    p_intf->p_sys->p_gnome->b_popup_changed = 0;
-    p_intf->p_sys->p_gnome->b_window_changed = 0;
-    p_intf->p_sys->p_gnome->b_playlist_changed = 0;
-
-    vlc_thread_create( &p_intf->p_sys->p_gnome->thread_id, "gnome",
-                       (void *)GnomeThread, p_intf->p_sys->p_gnome );
-
-    /* create basic key bindings */
-    intf_AssignNormalKeys( p_intf );
-    
-
-    /* Disable screen saver and return */
-    p_intf->p_sys->i_ss_count = 1;
-    GnomeDisableScreenSaver( p_intf );
-    return( 0 );
-}
+static gint GnomeManage    ( gpointer p_data );
 
 /*****************************************************************************
- * intf_GnomeDestroy: destroy interface window
+ * g_atexit: kludge to avoid the Gnome thread to segfault at exit
+ *****************************************************************************
+ * gtk_init() makes several calls to g_atexit() which calls atexit() to
+ * register tidying callbacks to be called at program exit. Since the Gnome
+ * plugin is likely to be unloaded at program exit, we have to export this
+ * symbol to intercept the g_atexit() calls. Talk about crude hack.
  *****************************************************************************/
-void intf_GnomeDestroy( intf_thread_t *p_intf )
+void g_atexit( GVoidFunc func )
 {
-    /* Enable screen saver */
-    GnomeEnableScreenSaver( p_intf );
+    intf_thread_t *p_intf = p_main->p_intf;
 
-    /* Close input thread, if any (blocking) */
-    if( p_intf->p_input )
+    if( p_intf->p_sys->pf_gdk_callback == NULL )
     {
-        input_DestroyThread( p_intf->p_input, NULL );
+        p_intf->p_sys->pf_gdk_callback = func;
     }
-
-    /* Close video output thread, if any (blocking) */
-    if( p_intf->p_vout )
+    else if( p_intf->p_sys->pf_gtk_callback == NULL )
     {
-        vout_DestroyThread( p_intf->p_vout, NULL );
+        p_intf->p_sys->pf_gtk_callback = func;
     }
-
-    /* Close gnome thread, if any (blocking) */
-    if( p_intf->p_sys->p_gnome->thread_id )
-    {
-        p_intf->p_sys->p_gnome->b_die = 1;
-        intf_DbgMsg( "intf: waiting for Gnome thread to terminate" );
-        vlc_thread_join( p_intf->p_sys->p_gnome->thread_id );
-        intf_DbgMsg( "intf: Gnome thread terminated" );
-    }
-
-    /* Close main window and display */
-    GnomeDestroyWindow( p_intf );
-    XCloseDisplay( p_intf->p_sys->p_display );
-
-    /* Destroy structures */
-    free( p_intf->p_sys->p_gnome );
-    free( p_intf->p_sys );
+    /* else nothing, but we could do something here */
+    return;
 }
 
 /*****************************************************************************
- * intf_GnomeManage: event loop
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
  *****************************************************************************/
-void intf_GnomeManage( intf_thread_t *p_intf )
+void intf_getfunctions( function_list_t * p_function_list )
 {
-    /* Manage main window */
-    GnomeManageWindow( p_intf );
-
-    /* Manage messages from the Gnome interface */
-    GnomeManageInterface( p_intf );
+    p_function_list->pf_probe = intf_Probe;
+    p_function_list->functions.intf.pf_open  = intf_Open;
+    p_function_list->functions.intf.pf_close = intf_Close;
+    p_function_list->functions.intf.pf_run   = intf_Run;
 }
 
-/* following functions are local */
-
 /*****************************************************************************
- * GnomeCreateWindow: open and set-up X11 main window
+ * intf_Probe: probe the interface and return a score
+ *****************************************************************************
+ * This function tries to initialize Gnome and returns a score to the
+ * plugin manager so that it can select the best plugin.
  *****************************************************************************/
-static int GnomeCreateWindow( intf_thread_t *p_intf )
+static int intf_Probe( probedata_t *p_data )
 {
-    XSizeHints              xsize_hints;
-    XSetWindowAttributes    xwindow_attributes;
-    XGCValues               xgcvalues;
-    XEvent                  xevent;
-    boolean_t               b_expose;
-    boolean_t               b_configure_notify;
-    boolean_t               b_map_notify;
-
-    /* Set main window's size */
-    p_intf->p_sys->i_width =  main_GetIntVariable( VOUT_WIDTH_VAR,
-                                                   VOUT_WIDTH_DEFAULT );
-    p_intf->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
-                                                   VOUT_HEIGHT_DEFAULT );
-
-    /* Prepare window manager hints and properties */
-    xsize_hints.base_width =            p_intf->p_sys->i_width;
-    xsize_hints.base_height =           p_intf->p_sys->i_height;
-    xsize_hints.flags =                 PSize;
-    p_intf->p_sys->wm_protocols =       XInternAtom( p_intf->p_sys->p_display,
-                                                     "WM_PROTOCOLS", True );
-    p_intf->p_sys->wm_delete_window =   XInternAtom( p_intf->p_sys->p_display,
-                                                     "WM_DELETE_WINDOW", True );
-
-    /* Prepare window attributes */
-    xwindow_attributes.backing_store = Always;       /* save the hidden part */
-    xwindow_attributes.background_pixel = WhitePixel( p_intf->p_sys->p_display,
-                                                      p_intf->p_sys->i_screen );
-
-    xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask;
-
-    /* Create the window and set hints - the window must receive ConfigureNotify
-     * events, and, until it is displayed, Expose and MapNotify events. */
-    p_intf->p_sys->window =
-            XCreateWindow( p_intf->p_sys->p_display,
-                           DefaultRootWindow( p_intf->p_sys->p_display ),
-                           0, 0,
-                           p_intf->p_sys->i_width, p_intf->p_sys->i_height, 1,
-                           0, InputOutput, 0,
-                           CWBackingStore | CWBackPixel | CWEventMask,
-                           &xwindow_attributes );
-
-    /* Set window manager hints and properties: size hints, command,
-     * window's name, and accepted protocols */
-    XSetWMNormalHints( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                       &xsize_hints );
-    XSetCommand( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                 p_main->ppsz_argv, p_main->i_argc );
-    XStoreName( p_intf->p_sys->p_display, p_intf->p_sys->window, VOUT_TITLE );
-    if( (p_intf->p_sys->wm_protocols == None)        /* use WM_DELETE_WINDOW */
-        || (p_intf->p_sys->wm_delete_window == None)
-        || !XSetWMProtocols( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                             &p_intf->p_sys->wm_delete_window, 1 ) )
-    {
-        /* WM_DELETE_WINDOW is not supported by window manager */
-        intf_Msg("intf error: missing or bad window manager - please exit program kindly.");
-    }
-
-    /* Creation of a graphic context that doesn't generate a GraphicsExpose
-     * event when using functions like XCopyArea */
-    xgcvalues.graphics_exposures = False;
-    p_intf->p_sys->gc =  XCreateGC( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                                    GCGraphicsExposures, &xgcvalues);
-
-    /* Send orders to server, and wait until window is displayed - three
-     * events must be received: a MapNotify event, an Expose event allowing
-     * drawing in the window, and a ConfigureNotify to get the window
-     * dimensions. Once those events have been received, only ConfigureNotify
-     * events need to be received. */
-    b_expose = 0;
-    b_configure_notify = 0;
-    b_map_notify = 0;
-    XMapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window);
-    do
-    {
-        XNextEvent( p_intf->p_sys->p_display, &xevent);
-        if( (xevent.type == Expose)
-            && (xevent.xexpose.window == p_intf->p_sys->window) )
-        {
-            b_expose = 1;
-        }
-        else if( (xevent.type == MapNotify)
-                 && (xevent.xmap.window == p_intf->p_sys->window) )
-        {
-            b_map_notify = 1;
-        }
-        else if( (xevent.type == ConfigureNotify)
-                 && (xevent.xconfigure.window == p_intf->p_sys->window) )
-        {
-            b_configure_notify = 1;
-            p_intf->p_sys->i_width = xevent.xconfigure.width;
-            p_intf->p_sys->i_height = xevent.xconfigure.height;
-        }
-    } while( !( b_expose && b_configure_notify && b_map_notify ) );
-
-    XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                  StructureNotifyMask | KeyPressMask | ButtonPressMask );
-
-    if( XDefaultDepth(p_intf->p_sys->p_display, p_intf->p_sys->i_screen) == 8 )
+    if( TestMethod( INTF_METHOD_VAR, "gnome" ) )
     {
-        /* Allocate a new palette */
-        p_intf->p_sys->colormap = XCreateColormap( p_intf->p_sys->p_display,
-                              DefaultRootWindow( p_intf->p_sys->p_display ),
-                              DefaultVisual( p_intf->p_sys->p_display,
-                                             p_intf->p_sys->i_screen ),
-                              AllocAll );
-
-        xwindow_attributes.colormap = p_intf->p_sys->colormap;
-        XChangeWindowAttributes( p_intf->p_sys->p_display,
-                                 p_intf->p_sys->window,
-                                 CWColormap, &xwindow_attributes );
+        return( 999 );
     }
 
-    /* At this stage, the window is open, displayed, and ready to receive data */
-    return( 0 );
-}
-
-/*****************************************************************************
- * GnomeDestroyWindow: destroy X11 main window
- *****************************************************************************/
-static void GnomeDestroyWindow( intf_thread_t *p_intf )
-{
-    XUnmapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
-    XFreeGC( p_intf->p_sys->p_display, p_intf->p_sys->gc );
-    XDestroyWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    return( 40 );
 }
 
 /*****************************************************************************
- * GnomeManageWindow: manage X11 main window
+ * intf_Open: initialize and create window
  *****************************************************************************/
-static void GnomeManageWindow( intf_thread_t *p_intf )
+static int intf_Open( intf_thread_t *p_intf )
 {
-    XEvent      xevent;                                         /* X11 event */
-    boolean_t   b_resized;                        /* window has been resized */
-    char        i_key;                                    /* ISO Latin-1 key */
-
-    /* Handle X11 events: ConfigureNotify events are parsed to know if the
-     * output window's size changed, MapNotify and UnmapNotify to know if the
-     * window is mapped (and if the display is useful), and ClientMessages
-     * to intercept window destruction requests */
-    b_resized = 0;
-    while( XCheckWindowEvent( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                              StructureNotifyMask | KeyPressMask |
-                              ButtonPressMask, &xevent ) == True )
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
     {
-        /* ConfigureNotify event: prepare  */
-        if( (xevent.type == ConfigureNotify)
-            && ((xevent.xconfigure.width != p_intf->p_sys->i_width)
-                || (xevent.xconfigure.height != p_intf->p_sys->i_height)) )
-        {
-            /* Update dimensions */
-            b_resized = 1;
-            p_intf->p_sys->i_width = xevent.xconfigure.width;
-            p_intf->p_sys->i_height = xevent.xconfigure.height;
-        }
-        /* MapNotify event: change window status and disable screen saver */
-        else if( xevent.type == MapNotify)
-        {
-            if( (p_intf->p_vout != NULL) && !p_intf->p_vout->b_active )
-            {
-                GnomeDisableScreenSaver( p_intf );
-                p_intf->p_vout->b_active = 1;
-            }
-        }
-        /* UnmapNotify event: change window status and enable screen saver */
-        else if( xevent.type == UnmapNotify )
-        {
-            if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_active )
-            {
-                GnomeEnableScreenSaver( p_intf );
-                p_intf->p_vout->b_active = 0;
-            }
-        }
-        /* Keyboard event */
-        else if( xevent.type == KeyPress )
-        {
-            if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
-            {
-                if( intf_ProcessKey( p_intf, i_key ) )
-                {
-                    intf_DbgMsg( "unhandled key '%c' (%i)", (char) i_key, i_key );
-                }
-            }
-        }
-        /* Mouse click */
-        else if( xevent.type == ButtonPress )
-        {
-            switch( ((XButtonEvent *)&xevent)->button )
-            {
-                case Button1:
-                    /* in this part we will eventually manage
-                     * clicks for DVD navigation for instance */
-                    break;
-
-                case Button2:
-                    GnomeTogglePointer( p_intf );
-                    break;
-
-                case Button3:
-                    /* toggle the menu display */
-                    vlc_mutex_lock( &p_intf->p_sys->p_gnome->change_lock );
-                    p_intf->p_sys->p_gnome->b_popup_changed = 1;
-                    vlc_mutex_unlock( &p_intf->p_sys->p_gnome->change_lock );
-                    break;
-            }
-
-        }
-#ifdef DEBUG
-        /* Other event */
-        else
-        {
-            intf_DbgMsg( "%p -> unhandled event type %d received",
-                         p_intf, xevent.type );
-        }
-#endif
+        intf_ErrMsg("error: %s", strerror(ENOMEM));
+        return( 1 );
     }
 
-    /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
-     * are handled - according to the man pages, the format is always 32
-     * in this case */
-    while( XCheckTypedEvent( p_intf->p_sys->p_display,
-                             ClientMessage, &xevent ) )
-    {
-        if( (xevent.xclient.message_type == p_intf->p_sys->wm_protocols)
-            && (xevent.xclient.data.l[0] == p_intf->p_sys->wm_delete_window ) )
-        {
-            p_intf->b_die = 1;
-        }
-        else
-        {
-            intf_DbgMsg( "%p -> unhandled ClientMessage received", p_intf );
-        }
-    }
+    /* Initialize Gnome thread */
+    p_intf->p_sys->b_window = 1;
+    p_intf->p_sys->b_playlist = 0;
 
-    /*
-     * Handle vout or interface windows resizing
-     */
-    if( p_intf->p_vout != NULL )
-    {
-        if( b_resized )
-        {
-            /* If interface window has been resized, change vout size */
-            intf_DbgMsg( "resizing output window" );
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->i_width =  p_intf->p_sys->i_width;
-            p_intf->p_vout->i_height = p_intf->p_sys->i_height;
-            p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-        }
-        else if( (p_intf->p_vout->i_width  != p_intf->p_sys->i_width) ||
-                 (p_intf->p_vout->i_height != p_intf->p_sys->i_height) )
-        {
-           /* If video output size has changed, change interface window size */
-            intf_DbgMsg( "resizing output window" );
-            p_intf->p_sys->i_width =    p_intf->p_vout->i_width;
-            p_intf->p_sys->i_height =   p_intf->p_vout->i_height;
-            XResizeWindow( p_intf->p_sys->p_display, p_intf->p_sys->window,
-                           p_intf->p_sys->i_width, p_intf->p_sys->i_height );
-        }
-    }
-}
+    p_intf->p_sys->b_popup_changed = 0;
+    p_intf->p_sys->b_window_changed = 0;
+    p_intf->p_sys->b_playlist_changed = 0;
 
-/*****************************************************************************
- * GnomeEnableScreenSaver: enable screen saver
- *****************************************************************************
- * This function enable the screen saver on a display after it had been
- * disabled by XDisableScreenSaver. Both functions use a counter mechanism to
- * know wether the screen saver can be activated or not: if n successive calls
- * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver
- * will be required before the screen saver could effectively be activated.
- *****************************************************************************/
-void GnomeEnableScreenSaver( intf_thread_t *p_intf )
-{
-    if( p_intf->p_sys->i_ss_count++ == 0 )
-    {
-        intf_DbgMsg( "intf: enabling screen saver" );
-        XSetScreenSaver( p_intf->p_sys->p_display, p_intf->p_sys->i_ss_timeout,
-                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
-                         p_intf->p_sys->i_ss_exposure );
-    }
+    p_intf->p_sys->pf_gtk_callback = NULL;
+    p_intf->p_sys->pf_gdk_callback = NULL;
+
+    return( 0 );
 }
 
 /*****************************************************************************
- * GnomeDisableScreenSaver: disable screen saver
- *****************************************************************************
- * See XEnableScreenSaver
+ * intf_Close: destroy interface window
  *****************************************************************************/
-void GnomeDisableScreenSaver( intf_thread_t *p_intf )
+static void intf_Close( intf_thread_t *p_intf )
 {
-    if( --p_intf->p_sys->i_ss_count == 0 )
-    {
-        /* Save screen saver informations */
-        XGetScreenSaver( p_intf->p_sys->p_display, &p_intf->p_sys->i_ss_timeout,
-                         &p_intf->p_sys->i_ss_interval, &p_intf->p_sys->i_ss_blanking,
-                         &p_intf->p_sys->i_ss_exposure );
-
-        /* Disable screen saver */
-        intf_DbgMsg("intf: disabling screen saver");
-        XSetScreenSaver( p_intf->p_sys->p_display, 0,
-                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
-                         p_intf->p_sys->i_ss_exposure );
-    }
+    /* Destroy structure */
+    free( p_intf->p_sys );
 }
 
 /*****************************************************************************
- * GnomeTogglePointer: hide or show the mouse pointer
+ * intf_Run: Gnome thread
  *****************************************************************************
- * This function hides the X pointer if it is visible by putting it at
- * coordinates (32,32) and setting the pointer sprite to a blank one. To
- * show it again, we disable the sprite and restore the original coordinates.
+ * this part of the interface is in a separate thread so that we can call
+ * gtk_main() from within it without annoying the rest of the program.
+ * XXX: the approach may look kludgy, and probably is, but I could not find
+ * a better way to dynamically load a Gnome interface at runtime.
  *****************************************************************************/
-void GnomeTogglePointer( intf_thread_t *p_intf )
+static void intf_Run( intf_thread_t *p_intf )
 {
-    static Cursor cursor;
-    static boolean_t b_cursor = 0;
+    /* gnome_init needs to know the command line. We don't care, so we
+     * give it an empty one */
+    char *p_args[] = { };
 
-    if( p_intf->p_sys->b_mouse )
-    {
-        p_intf->p_sys->b_mouse = 0;
+    /* Initialize Gnome */
+    gnome_init( p_main->psz_arg0, VERSION, 1, p_args );
 
-        if( !b_cursor )
-        {
-            XColor color;
-            Pixmap blank = XCreatePixmap( p_intf->p_sys->p_display,
-                               DefaultRootWindow(p_intf->p_sys->p_display),
-                               1, 1, 1 );
-
-            XParseColor( p_intf->p_sys->p_display,
-                         XCreateColormap( p_intf->p_sys->p_display,
-                                          DefaultRootWindow(
-                                                  p_intf->p_sys->p_display ),
-                                          DefaultVisual(
-                                                  p_intf->p_sys->p_display,
-                                                  p_intf->p_sys->i_screen ),
-                                          AllocNone ),
-                         "black", &color );
-
-            cursor = XCreatePixmapCursor( p_intf->p_sys->p_display,
-                           blank, blank, &color, &color, 1, 1 );
-
-            b_cursor = 1;
-        }
-        XDefineCursor( p_intf->p_sys->p_display,
-                       p_intf->p_sys->window, cursor );
-    }
-    else
-    {
-        p_intf->p_sys->b_mouse = 1;
+    /* create some useful widgets that will certainly be used */
+    p_intf->p_sys->p_window = create_intf_window();
+    p_intf->p_sys->p_popup = create_intf_popup( );
 
-        XUndefineCursor( p_intf->p_sys->p_display, p_intf->p_sys->window );
-    }
-}
+    /* we don't create these ones yet because we perhaps won't need them */
+    p_intf->p_sys->p_about = NULL;
+    p_intf->p_sys->p_playlist = NULL;
 
-/*****************************************************************************
- * GnomeManageInterface: manage messages from the Gnome interface
+    /* store p_sys to keep an eye on it */
+    gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
+                         "p_intf", p_intf );
 
- *****************************************************************************
- * In this function, called approx. 10 times a second, we check what the
- * Gnome interface wanted to tell us.
- *****************************************************************************/
-static void GnomeManageInterface( intf_thread_t *p_intf )
-{
-    gnome_thread_t *p_gnome = p_intf->p_sys->p_gnome;
+    gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_popup),
+                         "p_intf", p_intf );
 
-    /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    /* show the control window */
+    gtk_widget_show( p_intf->p_sys->p_window );
 
-    /* you killed my father, prepare to die */
-    if( p_gnome->b_die )
-    {
-        p_intf->b_die = 1;
-    }
+    /* Sleep to avoid using all CPU - since some interfaces needs to access
+     * keyboard events, a 100ms delay is a good compromise */
+    p_intf->p_sys->i_timeout = gtk_timeout_add( INTF_IDLE_SLEEP / 1000,
+                                                GnomeManage, p_intf );
+ 
+    /* enter gnome mode */
+    gtk_main();
 
-    if( p_gnome->b_activity_changed )
+    /* launch stored callbacks */
+    if( p_intf->p_sys->pf_gtk_callback != NULL )
     {
-        vlc_mutex_lock( &p_intf->p_vout->picture_lock );
-        p_intf->p_vout->b_active = p_gnome->b_activity;
-        /* having to access p_main sucks */
-        p_main->p_aout->b_active = p_gnome->b_activity;
-        vlc_mutex_unlock( &p_intf->p_vout->picture_lock );
+        p_intf->p_sys->pf_gtk_callback();
 
-        p_gnome->b_activity_changed = 0;
+        if( p_intf->p_sys->pf_gdk_callback != NULL )
+        {
+            p_intf->p_sys->pf_gdk_callback();
+        }
     }
-
-    /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
 }
 
+/* following functions are local */
+
 /*****************************************************************************
- * GnomeManageMain: manage main thread messages
+ * GnomeManage: manage main thread messages
  *****************************************************************************
  * In this function, called approx. 10 times a second, we check what the
  * main program wanted to tell us.
  *****************************************************************************/
-static gint GnomeManageMain( gpointer p_data )
+static gint GnomeManage( gpointer p_data )
 {
-    gnome_thread_t *p_gnome = (void *)p_data;
-
-    /* lock the change structure */
-    vlc_mutex_lock( &p_gnome->change_lock );
+    intf_thread_t *p_intf = (void *)p_data;
 
-    if( p_gnome->b_die )
+    /* if the "display popup" flag has changed */
+    if( p_intf->b_menu_change )
     {
-        /* unlock the change structure */
-        vlc_mutex_unlock( &p_gnome->change_lock );
+        gnome_popup_menu_do_popup( p_intf->p_sys->p_popup,
+                                   NULL, NULL, NULL, NULL );
+        p_intf->b_menu_change = 0;
+    }
 
+    /* Manage core vlc functions through the callback */
+    p_intf->pf_manage( p_intf );
+
+    if( p_intf->b_die )
+    {
         /* prepare to die, young man */
         gtk_main_quit();
         return( FALSE );
     }
 
-    /* if the "display popup" flag has changed */
-    if( p_gnome->b_popup_changed )
-    {
-        gnome_popup_menu_do_popup( p_gnome->p_popup,
-                                   NULL, NULL, NULL, NULL );
-        p_gnome->b_popup_changed = 0;
-    }
-
-    /* unlock the change structure */
-    vlc_mutex_unlock( &p_gnome->change_lock );
-
     return( TRUE );
 }
 
-/*****************************************************************************
- * GnomeThread: special Gnome thread
- *****************************************************************************
- * this part of the interface is in a separate thread so that we can call
- * gtk_main() from within it without annoying the rest of the program.
- * XXX: the approach may look kludgy, and probably is, but I could not find
- * a better way to dynamically load a Gnome interface at runtime.
- *****************************************************************************/
-void GnomeThread( gnome_thread_t *p_gnome )
-{
-    /* gnome_init needs to know the command line. We don't care, so we
-     * give it an empty one */
-    char *p_args[] = { };
-
-    /* Sleep to avoid using all CPU - since some interfaces needs to access
-     * keyboard events, a 100ms delay is a good compromise */
-    gtk_timeout_add( INTF_IDLE_SLEEP / 1000, GnomeManageMain, p_gnome );
- 
-    gnome_init( "vlc", VERSION, 1, p_args );
-
-    /* create some useful widgets that will certainly be used */
-    p_gnome->p_window = create_intf_window();
-    p_gnome->p_popup = create_intf_popup( );
-
-    /* we don't create these ones yet because we perhaps won't need them */
-    p_gnome->p_about = NULL;
-    p_gnome->p_playlist = NULL;
-
-    /* store p_sys to keep an eye on it */
-    gtk_object_set_data( GTK_OBJECT(p_gnome->p_window), "p_gnome", p_gnome );
-    gtk_object_set_data( GTK_OBJECT(p_gnome->p_popup), "p_gnome", p_gnome );
-
-    /* show the control window */
-    //gtk_widget_show( p_gnome->p_window );
-
-    /* enter gnome mode */
-    gtk_main();
-}
-
diff --git a/plugins/gnome/intf_gnome.h b/plugins/gnome/intf_gnome.h
deleted file mode 100644
index 198e54e93e8db222701c7551125ea6898f52dd84..0000000000000000000000000000000000000000
--- a/plugins/gnome/intf_gnome.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************
- * intf_gnome.h: Gnome interface
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * 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
- * Boston, MA 02111-1307, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * intf_sys_t: description and status of Gnome interface
- *****************************************************************************/
-typedef struct intf_sys_s
-{
-    /* X11 generic properties */
-    Display *           p_display;                    /* X11 display pointer */
-    int                 i_screen;                              /* X11 screen */
-    Atom                wm_protocols;
-    Atom                wm_delete_window;
-
-    /* Main window properties */
-    Window              window;                               /* main window */
-    GC                  gc;               /* graphic context for main window */
-    int                 i_width;                     /* width of main window */
-    int                 i_height;                   /* height of main window */
-    Colormap            colormap;               /* colormap used (8bpp only) */
-
-    /* Screen saver properties */
-    int                 i_ss_count;              /* enabling/disabling count */
-    int                 i_ss_timeout;                             /* timeout */
-    int                 i_ss_interval;           /* interval between changes */
-    int                 i_ss_blanking;                      /* blanking mode */
-    int                 i_ss_exposure;                      /* exposure mode */
-
-    /* Mouse pointer properties */
-    boolean_t           b_mouse;         /* is the mouse pointer displayed ? */
-
-    /* Gnome part properties */
-    gnome_thread_t *    p_gnome;
-
-} intf_sys_t;
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  GnomeCreateWindow             ( intf_thread_t *p_intf );
-static void GnomeDestroyWindow            ( intf_thread_t *p_intf );
-static void GnomeManageInterface          ( intf_thread_t *p_intf );
-static gint GnomeManageMain               ( gpointer p_data );
-static void GnomeManageWindow             ( intf_thread_t *p_intf );
-static void GnomeEnableScreenSaver        ( intf_thread_t *p_intf );
-static void GnomeDisableScreenSaver       ( intf_thread_t *p_intf );
-static void GnomeTogglePointer            ( intf_thread_t *p_intf );
-
diff --git a/plugins/gnome/vout_gnome.c b/plugins/gnome/vout_gnome.c
deleted file mode 100644
index fe4443d9cbdd901c4e5df0b656c78fdc3791220a..0000000000000000000000000000000000000000
--- a/plugins/gnome/vout_gnome.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*****************************************************************************
- * vout_gnome.c: Gnome video output display method
- *****************************************************************************
- * Copyright (C) 1998, 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * 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 "defs.h"
-
-#include <errno.h>                                                 /* ENOMEM */
-#include <stdlib.h>                                                /* free() */
-#include <string.h>                                            /* strerror() */
-
-#ifdef SYS_BSD
-#include <sys/types.h>                                     /* typedef ushort */
-#endif
-
-#include <sys/shm.h>                                   /* shmget(), shmctl() */
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
-
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-#include "plugins.h"
-
-#include "video.h"
-#include "video_output.h"
-
-#include "intf_msg.h"
-
-/*****************************************************************************
- * vout_sys_t: video output X11 method descriptor
- *****************************************************************************
- * This structure is part of the video output thread descriptor.
- * It describes the X11 specific properties of an output thread. X11 video
- * output is performed through regular resizable windows. Windows can be
- * dynamically resized to adapt to the size of the streams.
- *****************************************************************************/
-typedef struct vout_sys_s
-{
-    /* User settings */
-    boolean_t           b_shm;               /* shared memory extension flag */
-
-    /* Internal settings and properties */
-    Display *           p_display;                        /* display pointer */
-    Visual *            p_visual;                          /* visual pointer */
-    int                 i_screen;                           /* screen number */
-    Window              root_window;                          /* root window */
-    Window              window;                   /* window instance handler */
-    GC                  gc;              /* graphic context instance handler */
-    Colormap            colormap;               /* colormap used (8bpp only) */
-
-    /* Display buffers and shared memory information */
-    XImage *            p_ximage[2];                       /* XImage pointer */
-    XShmSegmentInfo     shm_info[2];       /* shared memory zone information */
-} vout_sys_t;
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display,
-                                  Window root_window, void *p_data );
-static void X11CloseDisplay     ( vout_thread_t *p_vout );
-static int  X11CreateWindow     ( vout_thread_t *p_vout );
-static void X11DestroyWindow    ( vout_thread_t *p_vout );
-static int  X11CreateImage      ( vout_thread_t *p_vout, XImage **pp_ximage );
-static void X11DestroyImage     ( XImage *p_ximage );
-static int  X11CreateShmImage   ( vout_thread_t *p_vout, XImage **pp_ximage,
-                                  XShmSegmentInfo *p_shm_info );
-static void X11DestroyShmImage  ( vout_thread_t *p_vout, XImage *p_ximage,
-                                  XShmSegmentInfo *p_shm_info );
-
-/*****************************************************************************
- * vout_GnomeCreate: allocate X11 video thread output method
- *****************************************************************************
- * This function allocate and initialize a X11 vout method. It uses some of the
- * vout properties to choose the window size, and change them according to the
- * actual properties of the display.
- *****************************************************************************/
-int vout_GnomeCreate( vout_thread_t *p_vout, char *psz_display,
-                    int i_root_window, void *p_data )
-{
-    /* Allocate structure */
-    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
-    if( p_vout->p_sys == NULL )
-    {
-        intf_ErrMsg("error: %s", strerror(ENOMEM) );
-        return( 1 );
-    }
-
-    /* Open and initialize device. This function issues its own error messages.
-     * Since XLib is usually not thread-safe, we can't use the same display
-     * pointer than the interface or another thread. However, the root window
-     * id is still valid. */
-    if( X11OpenDisplay( p_vout, psz_display, i_root_window, p_data ) )
-    {
-        intf_ErrMsg("error: can't initialize X11 display" );
-        free( p_vout->p_sys );
-        return( 1 );
-    }
-
-    return( 0 );
-}
-
-/*****************************************************************************
- * vout_GnomeInit: initialize X11 video thread output method
- *****************************************************************************
- * This function create the XImages needed by the output thread. It is called
- * at the beginning of the thread, but also each time the window is resized.
- *****************************************************************************/
-int vout_GnomeInit( vout_thread_t *p_vout )
-{
-    int i_err;
-
-    /* Create XImages using XShm extension - on failure, fall back to regular
-     * way (and destroy the first image if it was created successfully) */
-    if( p_vout->p_sys->b_shm )
-    {
-        /* Create first image */
-        i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0],
-                                   &p_vout->p_sys->shm_info[0] );
-        if( !i_err )                         /* first image has been created */
-        {
-            /* Create second image */
-            if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1],
-                                   &p_vout->p_sys->shm_info[1] ) )
-            {                             /* error creating the second image */
-                X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
-                                    &p_vout->p_sys->shm_info[0] );
-                i_err = 1;
-            }
-        }
-        if( i_err )                                      /* an error occured */
-        {
-            intf_Msg("vout: XShm video extension deactivated" );
-            p_vout->p_sys->b_shm = 0;
-        }
-    }
-
-    /* Create XImages without XShm extension */
-    if( !p_vout->p_sys->b_shm )
-    {
-        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) )
-        {
-            intf_ErrMsg("error: can't create images");
-            p_vout->p_sys->p_ximage[0] = NULL;
-            p_vout->p_sys->p_ximage[1] = NULL;
-            return( 1 );
-        }
-        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) )
-        {
-            intf_ErrMsg("error: can't create images");
-            X11DestroyImage( p_vout->p_sys->p_ximage[0] );
-            p_vout->p_sys->p_ximage[0] = NULL;
-            p_vout->p_sys->p_ximage[1] = NULL;
-            return( 1 );
-        }
-    }
-
-    /* Set bytes per line and initialize buffers */
-    p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
-    vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
-                     p_vout->p_sys->p_ximage[ 1 ]->data );
-    return( 0 );
-}
-
-/*****************************************************************************
- * vout_GnomeEnd: terminate X11 video thread output method
- *****************************************************************************
- * Destroy the X11 XImages created by vout_SysInit. It is called at the end of
- * the thread, but also each time the window is resized.
- *****************************************************************************/
-void vout_GnomeEnd( vout_thread_t *p_vout )
-{
-    if( p_vout->p_sys->b_shm )                             /* Shm XImages... */
-    {
-        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
-                            &p_vout->p_sys->shm_info[0] );
-        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1],
-                            &p_vout->p_sys->shm_info[1] );
-    }
-    else                                          /* ...or regular XImages */
-    {
-        X11DestroyImage( p_vout->p_sys->p_ximage[0] );
-        X11DestroyImage( p_vout->p_sys->p_ximage[1] );
-    }
-}
-
-/*****************************************************************************
- * vout_GnomeDestroy: destroy X11 video thread output method
- *****************************************************************************
- * Terminate an output method created by vout_CreateOutputMethod
- *****************************************************************************/
-void vout_GnomeDestroy( vout_thread_t *p_vout )
-{
-    X11CloseDisplay( p_vout );
-    free( p_vout->p_sys );
-}
-
-/*****************************************************************************
- * vout_GnomeManage: handle X11 events
- *****************************************************************************
- * This function should be called regularly by video output thread. It manages
- * X11 events and allows window resizing. It returns a non null value on
- * error.
- *****************************************************************************/
-int vout_GnomeManage( vout_thread_t *p_vout )
-{
-    /*
-     * Color/Grayscale or gamma change: in 8bpp, just change the colormap
-     */
-    if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
-    {
-        /* FIXME: clear flags ?? */
-    }
-
-    /*
-     * Size change
-     */
-    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
-    {
-        intf_DbgMsg("resizing window");
-        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
-
-        /* Resize window */
-        XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
-                       p_vout->i_width, p_vout->i_height );
-
-        /* Destroy XImages to change their size */
-        vout_GnomeEnd( p_vout );
-
-        /* Recreate XImages. If SysInit failed, the thread can't go on. */
-        if( vout_GnomeInit( p_vout ) )
-        {
-            intf_ErrMsg("error: can't resize display");
-            return( 1 );
-        }
-
-        /* Tell the video output thread that it will need to rebuild YUV
-         * tables. This is needed since convertion buffer size may have changed */
-        p_vout->i_changes |= VOUT_YUV_CHANGE;
-        intf_Msg("vout: video display resized (%dx%d)", p_vout->i_width, p_vout->i_height);
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * vout_GnomeDisplay: displays previously rendered output
- *****************************************************************************
- * This function send the currently rendered image to X11 server, wait until
- * it is displayed and switch the two rendering buffer, preparing next frame.
- *****************************************************************************/
-void vout_GnomeDisplay( vout_thread_t *p_vout )
-{
-    if( p_vout->p_sys->b_shm)                                /* XShm is used */
-    {
-        /* Display rendered image using shared memory extension */
-        XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
-                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
-                     0, 0, 0, 0,
-                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
-                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True);
-
-        /* Send the order to the X server */
-        XFlush(p_vout->p_sys->p_display);
-    }
-    else                                /* regular X11 capabilities are used */
-    {
-        XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
-                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
-                  0, 0, 0, 0,
-                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
-                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height);
-
-        /* Send the order to the X server */
-        XFlush(p_vout->p_sys->p_display);
-    }
-}
-
-/*****************************************************************************
- * vout_GnomeSetPalette: sets an 8 bpp palette
- *****************************************************************************
- * This function sets the palette given as an argument. It does not return
- * anything, but could later send information on which colors it was unable
- * to set.
- *****************************************************************************/
-void vout_GnomeSetPalette( p_vout_thread_t p_vout,
-                           u16 *red, u16 *green, u16 *blue, u16 *transp )
-{
-    int i;
-    XColor color[255];
-
-    intf_DbgMsg( "Palette change called" );
-
-    /* allocate palette */
-    for( i = 0; i < 255; i++ )
-    {
-        /* kludge: colors are indexed reversely because color 255 seems
-         * to be reserved for black even if we try to set it to white */
-        color[i].pixel = 255-i;
-        color[i].pad = 0;
-        color[i].flags = DoRed|DoGreen|DoBlue;
-        color[i].red = red[255-i];
-        color[i].blue = blue[255-i];
-        color[i].green = green[255-i];
-    }
-
-    XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
-}
-
-/* following functions are local */
-
-/*****************************************************************************
- * X11OpenDisplay: open and initialize X11 device
- *****************************************************************************
- * Create a window according to video output given size, and set other
- * properties according to the display properties.
- *****************************************************************************/
-static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data )
-{
-    XPixmapFormatValues *       p_xpixmap_format;          /* pixmap formats */
-    XVisualInfo *               p_xvisual;           /* visuals informations */
-    XVisualInfo                 xvisual_template;         /* visual template */
-    int                         i_count;                       /* array size */
-
-    /* Open display */
-    p_vout->p_sys->p_display = XOpenDisplay( psz_display );
-    if( p_vout->p_sys->p_display == NULL )
-    {
-        intf_ErrMsg("error: can't open display %s", psz_display );
-        return( 1 );
-    }
-
-    /* Initialize structure */
-    p_vout->p_sys->root_window  = root_window;
-    p_vout->p_sys->b_shm        = (XShmQueryExtension(p_vout->p_sys->p_display) == True);
-    p_vout->p_sys->i_screen     = DefaultScreen( p_vout->p_sys->p_display );
-    if( !p_vout->p_sys->b_shm )
-    {
-        intf_Msg("vout: XShm video extension is not available");
-    }
-
-    /* Get screen depth */
-    p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );
-    switch( p_vout->i_screen_depth )
-    {
-    case 8:
-        /*
-         * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
-         */
-        xvisual_template.screen =   p_vout->p_sys->i_screen;
-        xvisual_template.class =    DirectColor;
-        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
-                                    &xvisual_template, &i_count );
-        if( p_xvisual == NULL )
-        {
-            intf_ErrMsg("error: no PseudoColor visual available");
-            XCloseDisplay( p_vout->p_sys->p_display );
-            return( 1 );
-        }
-        p_vout->i_bytes_per_pixel = 1;
-
-        /* put the colormap in place */
-        p_vout->p_sys->colormap = *(Colormap *)p_data;
-        break;
-    case 15:
-    case 16:
-    case 24:
-    default:
-        /*
-         * Screen depth is higher than 8bpp. TrueColor visual is used.
-         */
-        xvisual_template.screen =   p_vout->p_sys->i_screen;
-        xvisual_template.class =    TrueColor;
-        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
-                                    &xvisual_template, &i_count );
-        if( p_xvisual == NULL )
-        {
-            intf_ErrMsg("error: no TrueColor visual available");
-            XCloseDisplay( p_vout->p_sys->p_display );
-            return( 1 );
-        }
-        p_vout->i_red_mask =        p_xvisual->red_mask;
-        p_vout->i_green_mask =      p_xvisual->green_mask;
-        p_vout->i_blue_mask =       p_xvisual->blue_mask;
-
-        /* There is no difference yet between 3 and 4 Bpp. The only way to find
-         * the actual number of bytes per pixel is to list supported pixmap
-         * formats. */
-        p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
-        p_vout->i_bytes_per_pixel = 0;
-
-        /* Under XFree 4, XListPixmapFormats returns a list of available
-         * formats under each screen depth ; so we have to select the one
-         * for the current display. */
-        for( ; i_count--; p_xpixmap_format++ )
-        {
-            if( p_vout->i_screen_depth == p_xpixmap_format->depth )
-            {
-                if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
-                {
-                    p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;
-                }
-            }
-        }
-        break;
-    }
-    p_vout->p_sys->p_visual = p_xvisual->visual;
-    XFree( p_xvisual );
-
-    /* Create a window */
-    if( X11CreateWindow( p_vout ) )
-    {
-        intf_ErrMsg("error: can't open a window");
-        XCloseDisplay( p_vout->p_sys->p_display );
-        return( 1 );
-    }
-    return( 0 );
-}
-
-/*****************************************************************************
- * X11CloseDisplay: close X11 device
- *****************************************************************************
- * Returns all resources allocated by X11OpenDisplay and restore the original
- * state of the display.
- *****************************************************************************/
-static void X11CloseDisplay( vout_thread_t *p_vout )
-{
-    /* Destroy colormap */
-    if( p_vout->i_screen_depth == 8 )
-    {
-        XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
-    }
-    
-    /* Destroy window */
-    X11DestroyWindow( p_vout );
-
-    /* FIXME: We should close the display here, but X returns an error. */
-    //XCloseDisplay( p_vout->p_sys->p_display );
-}
-
-/*****************************************************************************
- * X11CreateWindow: create X11 vout window
- *****************************************************************************
- * The video output window will be created. Normally, this window is wether
- * full screen or part of a parent window. Therefore, it does not need a
- * title or other hints. Thery are still supplied in case the window would be
- * spawned as a standalone one by the interface.
- *****************************************************************************/
-static int X11CreateWindow( vout_thread_t *p_vout )
-{
-    XSetWindowAttributes    xwindow_attributes;         /* window attributes */
-    XGCValues               xgcvalues;      /* graphic context configuration */
-    XEvent                  xevent;                          /* first events */
-    boolean_t               b_expose;             /* 'expose' event received */
-    boolean_t               b_map_notify;     /* 'map_notify' event received */
-
-    /* Prepare window attributes */
-    xwindow_attributes.backing_store = Always;       /* save the hidden part */
-
-    /* Create the window and set hints */
-    p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
-                                         p_vout->p_sys->root_window,
-                                         0, 0,
-                                         p_vout->i_width, p_vout->i_height,
-                                         0, 0, 0);
-    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
-                  ExposureMask | StructureNotifyMask );
-    XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
-                             CWBackingStore, &xwindow_attributes);
-
-    /* Creation of a graphic context that doesn't generate a GraphicsExpose event
-       when using functions like XCopyArea */
-    xgcvalues.graphics_exposures = False;
-    p_vout->p_sys->gc =  XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
-                                    GCGraphicsExposures, &xgcvalues);
-
-    /* Send orders to server, and wait until window is displayed - two events
-     * must be received: a MapNotify event, an Expose event allowing drawing in the
-     * window */
-    b_expose = 0;
-    b_map_notify = 0;
-    XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
-    do
-    {
-        XNextEvent( p_vout->p_sys->p_display, &xevent);
-        if( (xevent.type == Expose)
-            && (xevent.xexpose.window == p_vout->p_sys->window) )
-        {
-            b_expose = 1;
-        }
-        else if( (xevent.type == MapNotify)
-                 && (xevent.xmap.window == p_vout->p_sys->window) )
-        {
-            b_map_notify = 1;
-        }
-    }
-    while( !( b_expose && b_map_notify ) );
-    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
-
-    /* At this stage, the window is open, displayed, and ready to receive
-     * data */
-    return( 0 );
-}
-
-/*****************************************************************************
- * X11DestroyWindow: destroy X11 window
- *****************************************************************************
- * Destroy an X11 window created by vout_CreateWindow
- *****************************************************************************/
-static void X11DestroyWindow( vout_thread_t *p_vout )
-{
-    XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
-    XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
-    XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
-}
-
-/*****************************************************************************
- * X11CreateImage: create an XImage
- *****************************************************************************
- * Create a simple XImage used as a buffer.
- *****************************************************************************/
-static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
-{
-    byte_t *    pb_data;                          /* image data storage zone */
-    int         i_quantum;                     /* XImage quantum (see below) */
-
-    /* Allocate memory for image */
-    p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
-    pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
-    if( !pb_data )                                                  /* error */
-    {
-        intf_ErrMsg("error: %s", strerror(ENOMEM));
-        return( 1 );
-    }
-
-    /* Optimize the quantum of a scanline regarding its size - the quantum is
-       a diviser of the number of bits between the start of two scanlines. */
-    if( !(( p_vout->i_bytes_per_line ) % 32) )
-    {
-        i_quantum = 32;
-    }
-    else
-    {
-        if( !(( p_vout->i_bytes_per_line ) % 16) )
-        {
-            i_quantum = 16;
-        }
-        else
-        {
-            i_quantum = 8;
-        }
-    }
-
-    /* Create XImage */
-    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
-                               p_vout->i_screen_depth, ZPixmap, 0, pb_data,
-                               p_vout->i_width, p_vout->i_height, i_quantum, 0);
-    if(! *pp_ximage )                                               /* error */
-    {
-        intf_ErrMsg( "error: XCreateImage() failed" );
-        free( pb_data );
-        return( 1 );
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * X11CreateShmImage: create an XImage using shared memory extension
- *****************************************************************************
- * Prepare an XImage for DisplayX11ShmImage function.
- * The order of the operations respects the recommandations of the mit-shm
- * document by J.Corbet and K.Packard. Most of the parameters were copied from
- * there.
- *****************************************************************************/
-static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage,
-                              XShmSegmentInfo *p_shm_info)
-{
-    /* Create XImage */
-    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
-                                  p_vout->i_screen_depth, ZPixmap, 0,
-                                  p_shm_info, p_vout->i_width, p_vout->i_height );
-    if(! *pp_ximage )                                               /* error */
-    {
-        intf_ErrMsg("error: XShmCreateImage() failed");
-        return( 1 );
-    }
-
-    /* Allocate shared memory segment - 0777 set the access permission
-     * rights (like umask), they are not yet supported by X servers */
-    p_shm_info->shmid = shmget( IPC_PRIVATE,
-                                (*pp_ximage)->bytes_per_line * (*pp_ximage)->height,
-                                IPC_CREAT | 0777);
-    if( p_shm_info->shmid < 0)                                      /* error */
-    {
-        intf_ErrMsg("error: can't allocate shared image data (%s)",
-                    strerror(errno));
-        XDestroyImage( *pp_ximage );
-        return( 1 );
-    }
-
-    /* Attach shared memory segment to process (read/write) */
-    p_shm_info->shmaddr = (*pp_ximage)->data = shmat(p_shm_info->shmid, 0, 0);
-    if(! p_shm_info->shmaddr )
-    {                                                               /* error */
-        intf_ErrMsg("error: can't attach shared memory (%s)",
-                    strerror(errno));
-        shmctl( p_shm_info->shmid, IPC_RMID, 0 );      /* free shared memory */
-        XDestroyImage( *pp_ximage );
-        return( 1 );
-    }
-
-    /* Mark the shm segment to be removed when there will be no more
-     * attachements, so it is automatic on process exit or after shmdt */
-    shmctl( p_shm_info->shmid, IPC_RMID, 0 );
-
-    /* Attach shared memory segment to X server (read only) */
-    p_shm_info->readOnly = True;
-    if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False )    /* error */
-    {
-        intf_ErrMsg("error: can't attach shared memory to X11 server");
-        shmdt( p_shm_info->shmaddr );     /* detach shared memory from process
-                                           * and automatic free                */
-        XDestroyImage( *pp_ximage );
-        return( 1 );
-    }
-
-    /* Send image to X server. This instruction is required, since having
-     * built a Shm XImage and not using it causes an error on XCloseDisplay */
-    XFlush( p_vout->p_sys->p_display );
-    return( 0 );
-}
-
-/*****************************************************************************
- * X11DestroyImage: destroy an XImage
- *****************************************************************************
- * Destroy XImage AND associated data. If pointer is NULL, the image won't be
- * destroyed (see vout_ManageOutputMethod())
- *****************************************************************************/
-static void X11DestroyImage( XImage *p_ximage )
-{
-    if( p_ximage != NULL )
-    {
-        XDestroyImage( p_ximage );                     /* no free() required */
-    }
-}
-
-/*****************************************************************************
- * X11DestroyShmImage
- *****************************************************************************
- * Destroy XImage AND associated data. Detach shared memory segment from
- * server and process, then free it. If pointer is NULL, the image won't be
- * destroyed (see vout_ManageOutputMethod())
- *****************************************************************************/
-static void X11DestroyShmImage( vout_thread_t *p_vout, XImage *p_ximage,
-                                XShmSegmentInfo *p_shm_info )
-{
-    /* If pointer is NULL, do nothing */
-    if( p_ximage == NULL )
-    {
-        return;
-    }
-
-    XShmDetach( p_vout->p_sys->p_display, p_shm_info );     /* detach from server */
-    XDestroyImage( p_ximage );
-    if( shmdt( p_shm_info->shmaddr ) )  /* detach shared memory from process */
-    {                                   /* also automatic freeing...         */
-        intf_ErrMsg( "error: can't detach shared memory (%s)",
-                     strerror(errno) );
-    }
-}
-
-
diff --git a/plugins/sdl/intf_sdl.c b/plugins/sdl/intf_sdl.c
deleted file mode 100644
index 71c9921335d74826d3bcd240bd561a675e56a266..0000000000000000000000000000000000000000
--- a/plugins/sdl/intf_sdl.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*****************************************************************************
- * intf_sdl.c: SDL interface plugin
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_sdl.c,v 1.32 2001/02/08 13:52:35 massiot Exp $
- *
- * Authors:
- *
- * 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 "defs.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <SDL/SDL.h>                                /* for all the SDL stuff */
-
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-#include "plugins.h"
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-
-#include "video.h"
-#include "video_output.h"
-
-
-#include "interface.h"
-#include "intf_msg.h"
-#include "keystrokes.h"
-
-#include "main.h"
-
-/* local prototype */
-void intf_SDL_Keymap( intf_thread_t * p_intf );
-
-/*****************************************************************************
- * intf_SDLCreate: initialize and create SDL interface
- *****************************************************************************/
-int intf_SDLCreate( intf_thread_t *p_intf )
-{
-    /* Check that b_video is set */
-    if( !p_main->b_video )
-    {
-        intf_ErrMsg( "error: SDL interface requires a video output thread" );
-        return( 1 );
-    }
-
-    /* Spawn video output thread */
-    p_intf->p_vout = vout_CreateThread( main_GetPszVariable( VOUT_DISPLAY_VAR,
-                                                             NULL), 0,
-                                        main_GetIntVariable( VOUT_WIDTH_VAR,
-                                                         VOUT_WIDTH_DEFAULT ),
-                                        main_GetIntVariable( VOUT_HEIGHT_VAR,
-                                                        VOUT_HEIGHT_DEFAULT ),
-                                        NULL, 0, NULL );
-
-    if( p_intf->p_vout == NULL )                                  /* error */
-    {
-        intf_ErrMsg( "error: can't create video output thread" );
-        free( p_intf->p_sys );
-        return( 1 );
-    }
-    intf_SDL_Keymap( p_intf );
-    return( 0 );
-}
-
-/*****************************************************************************
- * intf_SDLDestroy: destroy interface
- *****************************************************************************/
-void intf_SDLDestroy( intf_thread_t *p_intf )
-{
-    /* Close input thread, if any (blocking) */
-    if( p_intf->p_input )
-    {
-        input_DestroyThread( p_intf->p_input, NULL );
-    }
-
-    /* Close video output thread, if any (blocking) */
-    if( p_intf->p_vout )
-    {
-        vout_DestroyThread( p_intf->p_vout, NULL );
-    }
-}
-
-
-/*****************************************************************************
- * intf_SDLManage: event loop
- *****************************************************************************/
-void intf_SDLManage( intf_thread_t *p_intf )
-{
-    SDL_Event event;                                            /* SDL event */
-    Uint8   i_key;
-    int     i_rate;
- 
-    while ( SDL_PollEvent(&event) )
-    {
-        switch (event.type)
-        {
-        case SDL_VIDEORESIZE:                           /* Resizing of window */
-            intf_Msg( "intf: video display resized (%dx%d)", event.resize.w
-                                                           , event.resize.h ); 
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->i_width = event.resize.w;
-            p_intf->p_vout->i_height = event.resize.h;
-            p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-            break;
-            
-        case SDL_KEYDOWN:                              /* if a key is pressed */
-            i_key = event.key.keysym.sym;
-               
-            switch(i_key) 
-            {
-            case SDLK_f:                              /* switch to fullscreen */
-                vlc_mutex_lock( &p_intf->p_vout->change_lock );
-                p_intf->p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
-                vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-                break;
-                
-            case SDLK_y:                                /* switch to hard YUV */
-                vlc_mutex_lock( &p_intf->p_vout->change_lock );
-                p_intf->p_vout->i_changes |= VOUT_YUV_CHANGE;
-                vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-                break; 
-
-            /* FIXME : this is temporary */
-            case SDLK_p:
-                if( p_intf->p_input->stream.control.i_status == PLAYING_S )
-                {
-                    input_Pause( p_intf->p_input );
-                }
-                else
-                {
-                    input_Play( p_intf->p_input );
-                }
-                break;
-
-            case SDLK_a:
-                i_rate = p_intf->p_input->stream.control.i_rate/2;
-                if ( i_rate >= MINIMAL_RATE )
-                {
-                    input_Forward( p_intf->p_input, i_rate );
-                }
-                break;
-
-            case SDLK_z:
-                i_rate = p_intf->p_input->stream.control.i_rate*2;
-                if ( i_rate <= MAXIMAL_RATE )
-                {
-                    /* Compensation of int truncature */
-                    if ( i_rate > 500 && i_rate < 1000 )
-                        i_rate = 1000;
-                    input_Forward( p_intf->p_input, i_rate );
-                }
-                break;
-
-            case SDLK_j:
-                /* Jump forwards */
-                input_Seek( p_intf->p_input,
-                            p_intf->p_input->stream.i_tell
-                             + p_intf->p_input->stream.i_size / 20 );
-                                                           /* gabuzomeu */
-                break;
-
-            case SDLK_b:
-                /* Jump backwards */
-                input_Seek( p_intf->p_input,
-                            p_intf->p_input->stream.i_tell
-                             - p_intf->p_input->stream.i_size / 20 );
-                break;
-
-            default:
-                if( intf_ProcessKey( p_intf, (char )i_key ) )
-                {
-                   intf_DbgMsg( "unhandled key '%c' (%i)", (char)i_key, i_key );
-                }
-                break;
-            }
-            break;
-            
-        case SDL_MOUSEBUTTONDOWN:
-            if( event.button.button == SDL_BUTTON_MIDDLE )
-            {
-                vlc_mutex_lock( &p_intf->p_vout->change_lock );
-                p_intf->p_vout->i_changes |= VOUT_CURSOR_CHANGE;
-                vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-            }                                       
-            break;
-            
-        case SDL_QUIT:
-            intf_ProcessKey( p_intf, SDLK_q );
-            break;
-       
-        default:
-            break;
-        }
-    }
-}
-
-void intf_SDL_Keymap(intf_thread_t * p_intf )
-{
-    /* p_intf->p_intf_getKey = intf_getKey; */
-    intf_AssignKey(p_intf, SDLK_q,      INTF_KEY_QUIT, 0);
-    intf_AssignKey(p_intf, SDLK_ESCAPE, INTF_KEY_QUIT, 0);
-    /* intf_AssignKey(p_intf,3,'Q'); */
-    intf_AssignKey(p_intf, SDLK_0,      INTF_KEY_SET_CHANNEL,0);
-    intf_AssignKey(p_intf, SDLK_1,      INTF_KEY_SET_CHANNEL,1);
-    intf_AssignKey(p_intf, SDLK_2,      INTF_KEY_SET_CHANNEL,2);
-    intf_AssignKey(p_intf, SDLK_3,      INTF_KEY_SET_CHANNEL,3);
-    intf_AssignKey(p_intf, SDLK_4,      INTF_KEY_SET_CHANNEL,4);
-    intf_AssignKey(p_intf, SDLK_5,      INTF_KEY_SET_CHANNEL,5);
-    intf_AssignKey(p_intf, SDLK_6,      INTF_KEY_SET_CHANNEL,6);
-    intf_AssignKey(p_intf, SDLK_7,      INTF_KEY_SET_CHANNEL,7);
-    intf_AssignKey(p_intf, SDLK_8,      INTF_KEY_SET_CHANNEL,8);
-    intf_AssignKey(p_intf, SDLK_9,      INTF_KEY_SET_CHANNEL,9);
-    intf_AssignKey(p_intf, SDLK_PLUS,   INTF_KEY_INC_VOLUME, 0);
-    intf_AssignKey(p_intf, SDLK_MINUS,  INTF_KEY_DEC_VOLUME, 0);
-    intf_AssignKey(p_intf, SDLK_m,      INTF_KEY_TOGGLE_VOLUME, 0);
-    /* intf_AssignKey(p_intf,'M','M'); */
-    intf_AssignKey(p_intf, SDLK_g,      INTF_KEY_DEC_GAMMA, 0);
-    /* intf_AssignKey(p_intf,'G','G'); */
-    intf_AssignKey(p_intf, SDLK_c,      INTF_KEY_TOGGLE_GRAYSCALE, 0);
-    intf_AssignKey(p_intf, SDLK_SPACE,  INTF_KEY_TOGGLE_INTERFACE, 0);
-    intf_AssignKey(p_intf, SDLK_i,         INTF_KEY_TOGGLE_INFO, 0);
-    intf_AssignKey(p_intf, SDLK_s,      INTF_KEY_TOGGLE_SCALING, 0);
-
-}
diff --git a/plugins/sdl/sdl.c b/plugins/sdl/sdl.c
index 54a17dfe4605706f3b3ce9f93b6cd513c0a97be5..8a1e4b6c8359ac90879a79fb803d25a240a651ae 100644
--- a/plugins/sdl/sdl.c
+++ b/plugins/sdl/sdl.c
@@ -36,14 +36,12 @@
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"
-#include "plugins.h"
 
-#include "interface.h"
 #include "audio_output.h"
+
 #include "video.h"
 #include "video_output.h"
 
-/* audio includes */
 #include "modules.h"
 #include "modules_inner.h"
 
@@ -59,6 +57,7 @@ MODULE_CONFIG_END
  * Capabilities defined in the other files.
  ******************************************************************************/
 extern void aout_getfunctions( function_list_t * p_function_list );
+extern void vout_getfunctions( function_list_t * p_function_list );
 
 /*****************************************************************************
  * InitModule: get the module structure and configuration.
@@ -75,6 +74,7 @@ int InitModule( module_t * p_module )
     p_module->psz_version = VERSION;
 
     p_module->i_capabilities = MODULE_CAPABILITY_NULL
+                                | MODULE_CAPABILITY_VOUT
                                 | MODULE_CAPABILITY_AOUT;
 
     return( 0 );
@@ -97,6 +97,7 @@ int ActivateModule( module_t * p_module )
     }
 
     aout_getfunctions( &p_module->p_functions->aout );
+    vout_getfunctions( &p_module->p_functions->vout );
 
     p_module->p_config = p_config;
 
@@ -117,82 +118,3 @@ int DeactivateModule( module_t * p_module )
     return( 0 );
 }
 
-/* old plugin API */
-
-/*****************************************************************************
- * Exported prototypes
- *****************************************************************************/
-static void vout_GetPlugin( p_vout_thread_t p_vout );
-static void intf_GetPlugin( p_intf_thread_t p_intf );
-
-/* Video output */
-int     vout_SDLCreate       ( vout_thread_t *p_vout, char *psz_display,
-                               int i_root_window, void *p_data );
-int     vout_SDLInit         ( p_vout_thread_t p_vout );
-void    vout_SDLEnd          ( p_vout_thread_t p_vout );
-void    vout_SDLDestroy      ( p_vout_thread_t p_vout );
-int     vout_SDLManage       ( p_vout_thread_t p_vout );
-void    vout_SDLDisplay      ( p_vout_thread_t p_vout );
-void    vout_SDLSetPalette   ( p_vout_thread_t p_vout,
-                               u16 *red, u16 *green, u16 *blue, u16 *transp );
-/* Interface */
-int     intf_SDLCreate       ( p_intf_thread_t p_intf );
-void    intf_SDLDestroy      ( p_intf_thread_t p_intf );
-void    intf_SDLManage       ( p_intf_thread_t p_intf );
-
-
-/*****************************************************************************
- * GetConfig: get the plugin structure and configuration
- *****************************************************************************/
-plugin_info_t * GetConfig( void )
-{
-    plugin_info_t * p_info = (plugin_info_t *) malloc( sizeof(plugin_info_t) );
-
-    p_info->psz_name    = "SDL (video)";
-    p_info->psz_version = VERSION;
-    p_info->psz_author  = "the VideoLAN team <vlc@videolan.org>";
-
-    p_info->aout_GetPlugin = NULL;
-    p_info->vout_GetPlugin = vout_GetPlugin;
-    p_info->intf_GetPlugin = intf_GetPlugin;
-    p_info->yuv_GetPlugin = NULL;
-  
-    
-    /* if the SDL libraries are there, assume we can enter the
-     * initialization part at least, even if we fail afterwards */
-    
-    p_info->i_score = 0x100;
-    
-    /* If this plugin was requested, score it higher */
-    if( TestMethod( VOUT_METHOD_VAR, "sdl" ) )
-    {
-        p_info->i_score += 0x200;
-    }
-
-    return( p_info );
-}
-
-/*****************************************************************************
- * Following functions are only called through the p_info structure
- *****************************************************************************/
-
-static void vout_GetPlugin( p_vout_thread_t p_vout )
-{
-    p_vout->p_sys_create  = vout_SDLCreate;
-    p_vout->p_sys_init    = vout_SDLInit;
-    p_vout->p_sys_end     = vout_SDLEnd;
-    p_vout->p_sys_destroy = vout_SDLDestroy;
-    p_vout->p_sys_manage  = vout_SDLManage;
-    p_vout->p_sys_display = vout_SDLDisplay;
-    p_vout->p_set_palette = vout_SDLSetPalette;
-
-}
-
-static void intf_GetPlugin( p_intf_thread_t p_intf )
-{
-    p_intf->p_sys_create  = intf_SDLCreate;
-    p_intf->p_sys_destroy = intf_SDLDestroy;
-    p_intf->p_sys_manage  = intf_SDLManage;
-}
-
-
diff --git a/plugins/sdl/vout_sdl.c b/plugins/sdl/vout_sdl.c
index 45478cc62db6c9041471da16e72ecbd2292a3ff7..c4e360d8bf29a80b26a12f440d82c007d6f13a2f 100644
--- a/plugins/sdl/vout_sdl.c
+++ b/plugins/sdl/vout_sdl.c
@@ -35,21 +35,40 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
+#include "tests.h"
+#include "modules.h"
+
+/* FIXME: it's up to the _interface_ to do this, not the video output */
+#include "stream_control.h"
+#include "input_ext-intf.h"
 
 #include "video.h"
 #include "video_output.h"
 
 #include "intf_msg.h"
+#include "interface.h"
+/* FIXME: get rid of this */
+#include "keystrokes.h"
 #include "main.h"
 
+/*****************************************************************************
+ * FIXME: this file is ...                                                   *
+ *                                                                           *
+ *    XXX     XXX         XXX XXX     XXX             XXX     XXX     XXX    *
+ *    XXX     XXX     XXX             XXX             XXX     XXX     XXX    *
+ *    XXX     XXX     XXX             XXX                 XXX         XXX    *
+ *    XXX     XXX     XXX     XXX     XXX                 XXX         XXX    *
+ *    XXX     XXX     XXX     XXX     XXX                 XXX                *
+ *        XXX             XXX XXX         XXX XXX         XXX         XXX    *
+ *                                                                           *
+ *****************************************************************************/
+
 /*****************************************************************************
  * vout_sys_t: video output SDL method descriptor
  *****************************************************************************
  * This structure is part of the video output thread descriptor.
  * It describes the SDL specific properties of an output thread.
  *****************************************************************************/
-/* FIXME: SOME CLUELESS MORON DEFINED THIS STRUCTURE IN INTF_SDL.C AS WELL   */
 typedef struct vout_sys_s
 {
     int i_width;
@@ -65,39 +84,73 @@ typedef struct vout_sys_s
 }   vout_sys_t;
 
 /*****************************************************************************
- * Local prototypes
+ * Local prototypes.
+ *****************************************************************************/
+static int  vout_Probe     ( probedata_t *p_data );
+static int  vout_Create    ( struct vout_thread_s * );
+static int  vout_Init      ( struct vout_thread_s * );
+static void vout_End       ( struct vout_thread_s * );
+static void vout_Destroy   ( struct vout_thread_s * );
+static int  vout_Manage    ( struct vout_thread_s * );
+static void vout_Display   ( struct vout_thread_s * );
+
+static int  SDLOpenDisplay      ( vout_thread_t *p_vout );
+static void SDLCloseDisplay     ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
  *****************************************************************************/
-static int     SDLOpenDisplay       ( vout_thread_t *p_vout );
-static void    SDLCloseDisplay      ( vout_thread_t *p_vout );
-static void    SDLToggleFullScreen  ( vout_thread_t *p_vout );
-static void    SDLTogglePointer     ( vout_thread_t *p_vout );
+void vout_getfunctions( function_list_t * p_function_list )
+{
+    p_function_list->pf_probe = vout_Probe;
+    p_function_list->functions.vout.pf_create     = vout_Create;
+    p_function_list->functions.vout.pf_init       = vout_Init;
+    p_function_list->functions.vout.pf_end        = vout_End;
+    p_function_list->functions.vout.pf_destroy    = vout_Destroy;
+    p_function_list->functions.vout.pf_manage     = vout_Manage;
+    p_function_list->functions.vout.pf_display    = vout_Display;
+    p_function_list->functions.vout.pf_setpalette = NULL;
+}
+
 /*****************************************************************************
- * vout_SDLCreate: allocate SDL video thread output method
+ * intf_Probe: probe the video driver and return a score
+ *****************************************************************************
+ * This function tries to initialize SDL and returns a score to the
+ * plugin manager so that it can select the best plugin.
+ *****************************************************************************/
+static int vout_Probe( probedata_t *p_data )
+{
+    if( TestMethod( VOUT_METHOD_VAR, "sdl" ) )
+    {
+        return( 999 );
+    }
+
+    return( 40 );
+}
+
+/*****************************************************************************
+ * vout_Create: allocate SDL video thread output method
  *****************************************************************************
  * This function allocate and initialize a SDL vout method. It uses some of the
  * vout properties to choose the correct mode, and change them according to the
  * mode actually used.
  *****************************************************************************/
-int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
-                    int i_root_window, void *p_data )
+int vout_Create( vout_thread_t *p_vout )
 {
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
     if( p_vout->p_sys == NULL )
     {
-        intf_ErrMsg( "error: %s", strerror(ENOMEM) );
+        intf_ErrMsg( "vout error: can't create p_sys (%s)", strerror(ENOMEM) );
         return( 1 );
     }
 
-    p_vout->p_sys->p_display = NULL;
-    p_vout->p_sys->p_overlay = NULL;
-
     /* Initialize library */
     if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE)
             < 0 )
     {
-        intf_ErrMsg( "error: can't initialize SDL library: %s",
-                     SDL_GetError() );
+        intf_ErrMsg( "vout error: can't initialize SDL (%s)", SDL_GetError() );
         free( p_vout->p_sys );
         return( 1 );
     }
@@ -105,8 +158,10 @@ int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
     /* Force the software yuv even if it is not used */
     /* If we don't do this, p_vout is not correctly initialized
        and it's impossible to switch between soft/hard yuv */
+    /* FIXME: this is a broken way to do !! fix this !! */
     p_vout->b_need_render = 1;
 
+    p_vout->p_sys->b_cursor = 1; /* TODO should be done with a main_GetInt.. */
     p_vout->p_sys->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR,
                                 VOUT_FULLSCREEN_DEFAULT );
     p_vout->p_sys->b_overlay = main_GetIntVariable( VOUT_OVERLAY_VAR,
@@ -116,70 +171,221 @@ int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
     p_vout->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
                                 VOUT_HEIGHT_DEFAULT );
 
-    p_vout->p_sys->b_cursor = 0 ;   // TODO should be done with a main_GetInt..
-    
+    p_vout->p_sys->p_display = NULL;
+    p_vout->p_sys->p_overlay = NULL;
+
     if( SDLOpenDisplay(p_vout) )
     {
-      intf_ErrMsg( "error: can't initialize SDL library: %s",
-                   SDL_GetError() );
-      free( p_vout->p_sys );
-      return( 1 );
+        intf_ErrMsg( "vout error: can't initialize SDL (%s)", SDL_GetError() );
+        free( p_vout->p_sys );
+        return( 1 );
     }
 
+    /* FIXME: get rid of this ASAP, it's FUCKING UGLY */
+    { intf_thread_t * p_intf = p_main->p_intf;
+    /* p_intf->p_intf_getKey = intf_getKey; */
+    intf_AssignKey(p_intf, SDLK_q,      INTF_KEY_QUIT, 0);
+    intf_AssignKey(p_intf, SDLK_ESCAPE, INTF_KEY_QUIT, 0);
+    /* intf_AssignKey(p_intf,3,'Q'); */
+    intf_AssignKey(p_intf, SDLK_0,      INTF_KEY_SET_CHANNEL,0);
+    intf_AssignKey(p_intf, SDLK_1,      INTF_KEY_SET_CHANNEL,1);
+    intf_AssignKey(p_intf, SDLK_2,      INTF_KEY_SET_CHANNEL,2);
+    intf_AssignKey(p_intf, SDLK_3,      INTF_KEY_SET_CHANNEL,3);
+    intf_AssignKey(p_intf, SDLK_4,      INTF_KEY_SET_CHANNEL,4);
+    intf_AssignKey(p_intf, SDLK_5,      INTF_KEY_SET_CHANNEL,5);
+    intf_AssignKey(p_intf, SDLK_6,      INTF_KEY_SET_CHANNEL,6);
+    intf_AssignKey(p_intf, SDLK_7,      INTF_KEY_SET_CHANNEL,7);
+    intf_AssignKey(p_intf, SDLK_8,      INTF_KEY_SET_CHANNEL,8);
+    intf_AssignKey(p_intf, SDLK_9,      INTF_KEY_SET_CHANNEL,9);
+    intf_AssignKey(p_intf, SDLK_PLUS,   INTF_KEY_INC_VOLUME, 0);
+    intf_AssignKey(p_intf, SDLK_MINUS,  INTF_KEY_DEC_VOLUME, 0);
+    intf_AssignKey(p_intf, SDLK_m,      INTF_KEY_TOGGLE_VOLUME, 0);
+    /* intf_AssignKey(p_intf,'M','M'); */
+    intf_AssignKey(p_intf, SDLK_g,      INTF_KEY_DEC_GAMMA, 0);
+    /* intf_AssignKey(p_intf,'G','G'); */
+    intf_AssignKey(p_intf, SDLK_c,      INTF_KEY_TOGGLE_GRAYSCALE, 0);
+    intf_AssignKey(p_intf, SDLK_SPACE,  INTF_KEY_TOGGLE_INTERFACE, 0);
+    intf_AssignKey(p_intf, SDLK_i,      INTF_KEY_TOGGLE_INFO, 0);
+    intf_AssignKey(p_intf, SDLK_s,      INTF_KEY_TOGGLE_SCALING, 0); }
+
     return( 0 );
 }
 
 /*****************************************************************************
- * vout_SDLInit: initialize SDL video thread output method
+ * vout_Init: initialize SDL video thread output method
  *****************************************************************************
  * This function initialize the SDL display device.
  *****************************************************************************/
-int vout_SDLInit( vout_thread_t *p_vout )
+int vout_Init( vout_thread_t *p_vout )
 {
     return( 0 );
 }
 
 /*****************************************************************************
- * vout_SDLEnd: terminate Sys video thread output method
+ * vout_End: terminate Sys video thread output method
  *****************************************************************************
  * Terminate an output method created by vout_SDLCreate
  *****************************************************************************/
-void vout_SDLEnd( vout_thread_t *p_vout )
+void vout_End( vout_thread_t *p_vout )
 {
     SDLCloseDisplay( p_vout );
     SDL_Quit();
 }
 
 /*****************************************************************************
- * vout_SDLDestroy: destroy Sys video thread output method
+ * vout_Destroy: destroy Sys video thread output method
  *****************************************************************************
  * Terminate an output method created by vout_SDLCreate
  *****************************************************************************/
-void vout_SDLDestroy( vout_thread_t *p_vout )
+void vout_Destroy( vout_thread_t *p_vout )
 {
     free( p_vout->p_sys );
 }
 
 /*****************************************************************************
- * vout_SDLManage: handle Sys events
+ * vout_Manage: handle Sys events
  *****************************************************************************
  * This function should be called regularly by video output thread. It returns
  * a non null value if an error occured.
  *****************************************************************************/
-int vout_SDLManage( vout_thread_t *p_vout )
+int vout_Manage( vout_thread_t *p_vout )
 {
+    SDL_Event event;                                            /* SDL event */
+    Uint8   i_key;
+    int     i_rate;
+
+    /* FIXME: do this nicely */
+    input_thread_t * p_input = p_main->p_intf->p_input;
+
+    /* Process events */
+    while( SDL_PollEvent(&event) )
+    {
+        switch( event.type )
+        {
+        case SDL_VIDEORESIZE:                          /* Resizing of window */
+            p_vout->i_width = event.resize.w;
+            p_vout->i_height = event.resize.h;
+            p_vout->i_changes |= VOUT_SIZE_CHANGE;
+            break;
+
+        case SDL_MOUSEBUTTONDOWN:
+            switch( event.button.button )
+            {
+            case SDL_BUTTON_MIDDLE:
+                p_vout->i_changes |= VOUT_CURSOR_CHANGE;
+                break;
+
+            case SDL_BUTTON_RIGHT:
+                p_main->p_intf->b_menu_change = 1;
+                break;
+            }
+            break;
+
+        case SDL_QUIT:
+            intf_ProcessKey( p_main->p_intf, SDLK_q );
+            break;
+
+        case SDL_KEYDOWN:                             /* if a key is pressed */
+            i_key = event.key.keysym.sym;
+
+            switch( i_key )
+            {
+            case SDLK_f:                             /* switch to fullscreen */
+                p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+                break;
+
+            case SDLK_y:                               /* switch to hard YUV */
+                p_vout->i_changes |= VOUT_YUV_CHANGE;
+                break;
+
+            case SDLK_c:                                 /* toggle grayscale */
+                p_vout->b_grayscale = ! p_vout->b_grayscale;
+               	p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
+                break;
+
+            case SDLK_i:                                      /* toggle info */
+                p_vout->b_info = ! p_vout->b_info;
+               	p_vout->i_changes |= VOUT_INFO_CHANGE;
+                break;
+
+	    case SDLK_s:                                   /* toggle scaling */
+                p_vout->b_scale = ! p_vout->b_scale;
+               	p_vout->i_changes |= VOUT_SCALE_CHANGE;
+                break;
+
+	    case SDLK_SPACE:                             /* toggle interface */
+                p_vout->b_interface = ! p_vout->b_interface;
+               	p_vout->i_changes |= VOUT_INTF_CHANGE;
+                break;
+
+            /* FIXME : this is temporary */
+            case SDLK_p:
+                if( p_input->stream.control.i_status == PLAYING_S )
+                {
+                    input_Pause( p_input );
+                }
+                else
+                {
+                    input_Play( p_input );
+                }
+                break;
+
+            case SDLK_a:
+                i_rate = p_input->stream.control.i_rate/2;
+                if ( i_rate >= MINIMAL_RATE )
+                {
+                    input_Forward( p_input, i_rate );
+                }
+                break;
+
+            case SDLK_z:
+                i_rate = p_input->stream.control.i_rate*2;
+                if ( i_rate <= MAXIMAL_RATE )
+                {
+                    /* Compensation of int truncature */
+                    if ( i_rate > 500 && i_rate < 1000 )
+                        i_rate = 1000;
+                    input_Forward( p_input, i_rate );
+                }
+                break;
+
+            case SDLK_j:
+                /* Jump forwards */
+                input_Seek( p_input, p_input->stream.i_tell
+                             + p_input->stream.i_size / 20 );
+                                                           /* gabuzomeu */
+                break;
+
+            case SDLK_b:
+                /* Jump backwards */
+                input_Seek( p_input, p_input->stream.i_tell
+                             - p_input->stream.i_size / 20 );
+                break;
+
+            default:
+                if( intf_ProcessKey( p_main->p_intf, (char )i_key ) )
+                {
+                   intf_DbgMsg( "unhandled key '%c' (%i)", (char)i_key, i_key );                }
+                break;
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
 
     /*
      * Size Change 
      */
-    if ( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
     {
         p_vout->p_sys->i_width = p_vout->i_width;
         p_vout->p_sys->i_height = p_vout->i_height;
 
         /* Need to reopen display */
         SDLCloseDisplay( p_vout );
-        if ( SDLOpenDisplay( p_vout ) )
+        if( SDLOpenDisplay( p_vout ) )
         {
           intf_ErrMsg( "error: can't open DISPLAY default display" );
           return( 1 );
@@ -190,52 +396,74 @@ int vout_SDLManage( vout_thread_t *p_vout )
     /*
      * YUV Change 
      */
-    if ( p_vout->i_changes & VOUT_YUV_CHANGE )
+    if( p_vout->i_changes & VOUT_YUV_CHANGE )
     {
-        p_vout->b_need_render = 1 - p_vout->b_need_render;
+        p_vout->b_need_render = ! p_vout->b_need_render;
         
         /* Need to reopen display */
         SDLCloseDisplay( p_vout );
-        if ( SDLOpenDisplay( p_vout ) )
+        if( SDLOpenDisplay( p_vout ) )
         {
           intf_ErrMsg( "error: can't open DISPLAY default display" );
           return( 1 );
         }
         p_vout->i_changes &= ~VOUT_YUV_CHANGE;
     }
-    
+
     /*
      * Fullscreen change
      */
-    if ( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
+    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
     {
-        p_vout->p_sys->b_fullscreen = 1 - p_vout->p_sys->b_fullscreen;
-        SDLToggleFullScreen( p_vout );
+        p_vout->p_sys->b_fullscreen = ! p_vout->p_sys->b_fullscreen;
+
+        if( p_vout->p_sys->b_fullscreen )
+        {
+            p_vout->p_sys->b_fullscreen = 0;
+            p_vout->p_sys->b_cursor = 1;
+            SDL_ShowCursor( 1 );
+        }
+        else
+        {
+            p_vout->p_sys->b_fullscreen = 1;
+            p_vout->p_sys->b_cursor = 0;
+            SDL_ShowCursor( 0 );
+        }
+
+        SDL_WM_ToggleFullScreen(p_vout->p_sys->p_display);
+
         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
     }
 
-    
-
     /*
      * Pointer change
      */
-    if ( p_vout->i_changes & VOUT_CURSOR_CHANGE )
+    if( p_vout->i_changes & VOUT_CURSOR_CHANGE )
     {
-        p_vout->p_sys->b_cursor = 1 - p_vout->p_sys->b_cursor;
-        SDLTogglePointer( p_vout );
+        if( p_vout->p_sys->b_cursor )
+        {
+            SDL_ShowCursor( 0 );
+            p_vout->p_sys->b_cursor = 0;
+        }
+        else
+        {
+            SDL_ShowCursor( 1 );
+            p_vout->p_sys->b_cursor = 1;
+        }
+        p_vout->i_changes &= ~VOUT_CURSOR_CHANGE;
     }
     
     return( 0 );
 }
 
 /*****************************************************************************
- * vout_SDLSetPalette: sets an 8 bpp palette
+ * vout_SetPalette: sets an 8 bpp palette
  *****************************************************************************
  * This function sets the palette given as an argument. It does not return
  * anything, but could later send information on which colors it was unable
  * to set.
  *****************************************************************************/
-void vout_SDLSetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green,
+void vout_SetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green,
                          u16 *blue, u16 *transp)
 {
      /* Create a display surface with a grayscale palette */
@@ -251,25 +479,25 @@ void vout_SDLSetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green,
     }
     
     /* Set palette */
-    if( SDL_SetColors(p_vout->p_sys->p_display, colors, 0, 256) == 0 )
+    if( SDL_SetColors( p_vout->p_sys->p_display, colors, 0, 256 ) == 0 )
     {
-        intf_ErrMsg( "vout error: failed setting palette\n" );
+        intf_ErrMsg( "vout error: failed setting palette" );
     }
 
 }
 
 /*****************************************************************************
- * vout_SDLDisplay: displays previously rendered output
+ * vout_Display: displays previously rendered output
  *****************************************************************************
  * This function send the currently rendered image to the display, wait until
  * it is displayed and switch the two rendering buffer, preparing next frame.
  *****************************************************************************/
-void vout_SDLDisplay( vout_thread_t *p_vout )
+void vout_Display( vout_thread_t *p_vout )
 {
     SDL_Rect    disp;
     if((p_vout->p_sys->p_display != NULL) && !p_vout->p_sys->b_reopen_display)
     {
-        if(p_vout->b_need_render)
+        if( p_vout->b_need_render )
         {  
             /* Change display frame */
             SDL_Flip( p_vout->p_sys->p_display );
@@ -383,8 +611,9 @@ static int SDLOpenDisplay( vout_thread_t *p_vout )
         SDL_ShowCursor( 1 );
 
     SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
-    SDL_EventState(SDL_KEYUP , SDL_IGNORE);                 /* ignore keys up */
+    SDL_EventState(SDL_KEYUP , SDL_IGNORE);                /* ignore keys up */
     SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);          
+
     if( p_vout->b_need_render )
     {
         p_vout->p_sys->p_buffer[ 0 ] = p_vout->p_sys->p_display->pixels;
@@ -449,51 +678,13 @@ static void SDLCloseDisplay( vout_thread_t *p_vout )
     {
         if( p_vout->p_sys->p_overlay != NULL )
         {            
-            SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay);
+            SDL_FreeYUVOverlay( p_vout->p_sys->p_overlay );
             p_vout->p_sys->p_overlay = NULL;
         }
+
         SDL_UnlockSurface ( p_vout->p_sys->p_display );
         SDL_FreeSurface( p_vout->p_sys->p_display );
         p_vout->p_sys->p_display = NULL;
     }
 }
 
-/*****************************************************************************
- * SDLToggleFullScreen: toggle fullscreen
- *****************************************************************************
- * This function toggles the fullscreen state of the surface.
- * And  - hide the pointer if switching to fullscreen
- *      - show the pointer if leaving fullscreen state
- *****************************************************************************/
-static void SDLToggleFullScreen( vout_thread_t *p_vout )
-{
-    SDL_WM_ToggleFullScreen(p_vout->p_sys->p_display);
-
-    if( p_vout->p_sys->b_fullscreen )
-    {
-        p_vout->p_sys->b_cursor=1;
-    }
-    else
-    {
-        p_vout->p_sys->b_cursor=0;
-    }
-    
-    SDLTogglePointer( p_vout );
-}
-
-/*****************************************************************************
- * SDLTogglePointer: Hide/Show mouse pointer
- *****************************************************************************
- * This function hides/shows the mouse pointer inside the main window.
- *****************************************************************************/
-static void SDLTogglePointer( vout_thread_t *p_vout )
-{
-    if( p_vout->p_sys->b_cursor==1 )
-    {
-        SDL_ShowCursor( 0 );
-    }
-    else
-    {
-        SDL_ShowCursor( 1 );
-    }
-}
diff --git a/plugins/yuv/video_yuv.c b/plugins/yuv/video_yuv.c
index 37e7d12072f0b30b5d96075da675ccb0a738c118..cdf8086b23c9250360833c0f728f2b42e3859f2a 100644
--- a/plugins/yuv/video_yuv.c
+++ b/plugins/yuv/video_yuv.c
@@ -227,7 +227,7 @@ static void SetYUV( vout_thread_t *p_vout )
                     transp[ i_index ] = 0;
                 }
                 /* the colors have been allocated, we can set the palette */
-                p_vout->p_set_palette( p_vout, bright, bright, bright, transp );
+                p_vout->pf_setpalette( p_vout, bright, bright, bright, transp );
                 p_vout->i_white_pixel = 0xff;
                 p_vout->i_black_pixel = 0x00;
                 p_vout->i_gray_pixel = 0x44;
@@ -325,7 +325,7 @@ static void SetYUV( vout_thread_t *p_vout )
                 /* the colors have been allocated, we can set the palette */
                 /* there will eventually be a way to know which colors
                  * couldn't be allocated and try to find a replacement */
-                p_vout->p_set_palette( p_vout, red, green, blue, transp );
+                p_vout->pf_setpalette( p_vout, red, green, blue, transp );
 
                 p_vout->i_white_pixel = 0xff;
                 p_vout->i_black_pixel = 0x00;
diff --git a/plugins/yuv/video_yuvmmx.c b/plugins/yuv/video_yuvmmx.c
index f7e72990cbcc937b3754bd5774a2249c599e1477..6beae71449fd416dce6e1be060232564846feaad 100644
--- a/plugins/yuv/video_yuvmmx.c
+++ b/plugins/yuv/video_yuvmmx.c
@@ -190,7 +190,7 @@ static void SetYUV( vout_thread_t *p_vout )
                 transp[ i_index ] = 0;
             }
             /* the colors have been allocated, we can set the palette */
-            p_vout->p_set_palette( p_vout, bright, bright, bright, transp );
+            p_vout->pf_setpalette( p_vout, bright, bright, bright, transp );
             p_vout->i_white_pixel = 0xff;
             p_vout->i_black_pixel = 0x00;
             p_vout->i_gray_pixel = 0x44;
@@ -263,7 +263,7 @@ static void SetYUV( vout_thread_t *p_vout )
             /* the colors have been allocated, we can set the palette */
             /* there will eventually be a way to know which colors
              * couldn't be allocated and try to find a replacement */
-            p_vout->p_set_palette( p_vout, red, green, blue, transp );
+            p_vout->pf_setpalette( p_vout, red, green, blue, transp );
 
             p_vout->i_white_pixel = 0xff;
             p_vout->i_black_pixel = 0x00;
diff --git a/src/ac3_decoder/ac3_decoder_thread.c b/src/ac3_decoder/ac3_decoder_thread.c
index 69b4e95f0a9b60db46f8a7311f03d70364292cae..c5bc8f9d42ca7b5ad8214b92928221d7f61473da 100644
--- a/src/ac3_decoder/ac3_decoder_thread.c
+++ b/src/ac3_decoder/ac3_decoder_thread.c
@@ -2,7 +2,7 @@
  * ac3_decoder_thread.c: ac3 decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: ac3_decoder_thread.c,v 1.23 2001/01/05 18:46:44 massiot Exp $
+ * $Id: ac3_decoder_thread.c,v 1.24 2001/02/11 01:15:10 sam Exp $
  *
  * Authors:
  *
@@ -44,7 +44,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 
diff --git a/src/ac3_decoder/ac3_exponent.c b/src/ac3_decoder/ac3_exponent.c
index ed0731816b35ea2a01f2df28f29a0454310c60e6..82ef2bdf5291af805592bf62f0d590524c3c0509 100644
--- a/src/ac3_decoder/ac3_exponent.c
+++ b/src/ac3_decoder/ac3_exponent.c
@@ -27,7 +27,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/audio_decoder/audio_decoder.c b/src/audio_decoder/audio_decoder.c
index 00fdb08870d69d038bebc127c479ee0a77360fcc..e110841f4527bdf4cef15f9205c7be5947ce59b1 100644
--- a/src/audio_decoder/audio_decoder.c
+++ b/src/audio_decoder/audio_decoder.c
@@ -2,7 +2,7 @@
  * audio_decoder.c: MPEG audio decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: audio_decoder.c,v 1.46 2001/01/11 17:44:48 sam Exp $
+ * $Id: audio_decoder.c,v 1.47 2001/02/11 01:15:10 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Michel Lespinasse <walken@via.ecp.fr>
@@ -45,7 +45,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
  
diff --git a/src/audio_output/audio_output.c b/src/audio_output/audio_output.c
index a5d3ce568ba17ff986b0f51ab6e8b70415020127..219eeb125924acf5e5db35d27005a6d2ee2ea2a8 100644
--- a/src/audio_output/audio_output.c
+++ b/src/audio_output/audio_output.c
@@ -46,7 +46,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
-#include "plugins.h"
 #include "modules.h"
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
@@ -112,7 +111,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
     }
 
     /* Choose the best module */
-    p_aout->p_module = module_Need( p_main->p_module_bank,
+    p_aout->p_module = module_Need( p_main->p_bank,
                                     MODULE_CAPABILITY_AOUT, NULL );
 
     if( p_aout->p_module == NULL )
@@ -135,7 +134,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
      */
     if ( p_aout->pf_open( p_aout ) )
     {
-        module_Unneed( p_main->p_module_bank, p_aout->p_module );
+        module_Unneed( p_main->p_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -146,7 +145,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
     if ( p_aout->pf_setformat( p_aout ) )
     {
         p_aout->pf_close( p_aout );
-        module_Unneed( p_main->p_module_bank, p_aout->p_module );
+        module_Unneed( p_main->p_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -160,7 +159,7 @@ aout_thread_t *aout_CreateThread( int *pi_status )
     if( aout_SpawnThread( p_aout ) )
     {
         p_aout->pf_close( p_aout );
-        module_Unneed( p_main->p_module_bank, p_aout->p_module );
+        module_Unneed( p_main->p_bank, p_aout->p_module );
         free( p_aout );
         return( NULL );
     }
@@ -338,7 +337,7 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
     p_aout->pf_close( p_aout );
 
     /* Release the aout module */
-    module_Unneed( p_main->p_module_bank, p_aout->p_module );
+    module_Unneed( p_main->p_bank, p_aout->p_module );
 
     /* Free structure */
     free( p_aout );
diff --git a/src/input/input.c b/src/input/input.c
index 02b8429225e9afd2bf141c1523880a33dfafbc2f..43bff2eed1ce2ca71071bd105b0e53877f3a9fb0 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.78 2001/02/08 13:52:35 massiot Exp $
+ * $Id: input.c,v 1.79 2001/02/11 01:15:11 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -115,7 +115,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
 
     /* Initialize default settings for spawned decoders */
     p_input->p_default_aout = p_main->p_aout;
-    p_input->p_default_vout = p_main->p_intf->p_vout;
+    p_input->p_default_vout = p_main->p_vout;
 
     /* Create thread and set locks. */
     vlc_mutex_init( &p_input->stream.stream_lock );
@@ -268,7 +268,7 @@ static void InitThread( input_thread_t * p_input )
     p_input->c_packets_trashed          = 0;
 #endif
 
-    p_input->p_input_module = module_Need( p_main->p_module_bank,
+    p_input->p_input_module = module_Need( p_main->p_bank,
                                            MODULE_CAPABILITY_INPUT, NULL );
 
     if( p_input->p_input_module == NULL )
@@ -297,7 +297,7 @@ static void InitThread( input_thread_t * p_input )
 
     if( p_input->b_error )
     {
-        module_Unneed( p_main->p_module_bank, p_input->p_input_module );
+        module_Unneed( p_main->p_bank, p_input->p_input_module );
     }
     else
     {
@@ -352,7 +352,7 @@ static void EndThread( input_thread_t * p_input )
     p_input->pf_end( p_input );
 
     /* Release modules */
-    module_Unneed( p_main->p_module_bank, p_input->p_input_module );
+    module_Unneed( p_main->p_bank, p_input->p_input_module );
 
     /* Destroy Mutex locks */
     vlc_mutex_destroy( &p_input->stream.control.control_lock );
diff --git a/src/interface/interface.c b/src/interface/interface.c
index a9625d8d86f21c62f50eafa325e24c751835fa4e..f7a35bedd631621f74a3a8d19686ef2887e8be7a 100644
--- a/src/interface/interface.c
+++ b/src/interface/interface.c
@@ -36,7 +36,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 #include "modules.h"
 
 #include "stream_control.h"
@@ -47,8 +46,8 @@
 #include "intf_msg.h"
 #include "interface.h"
 #include "intf_cmd.h"
-#include "intf_console.h"
 #include "intf_plst.h"
+#include "intf_channels.h"
 #include "keystrokes.h"
 
 #include "video.h"
@@ -56,33 +55,10 @@
 
 #include "main.h"
 
-/*****************************************************************************
- * intf_channel_t: channel description
- *****************************************************************************
- * A 'channel' is a descriptor of an input method. It is used to switch easily
- * from source to source without having to specify the whole input thread
- * configuration. The channels array, stored in the interface thread object, is
- * loaded in intf_Create, and unloaded in intf_Destroy.
- *****************************************************************************/
-typedef struct intf_channel_s
-{
-    /* Channel description */
-    int         i_channel;            /* channel number, -1 for end of array */
-    char *      psz_description;              /* channel description (owned) */
-
-    /* Input configuration */
-    int         i_input_method;                   /* input method descriptor */
-    char *      psz_input_source;                   /* source string (owned) */
-    int         i_input_port;                                        /* port */
-    int         i_input_vlan_id;                                  /* vlan id */
-} intf_channel_t;
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int      LoadChannels    ( intf_thread_t *p_intf, char *psz_filename );
-static void     UnloadChannels  ( intf_thread_t *p_intf );
-static int      ParseChannel    ( intf_channel_t *p_channel, char *psz_str );
+static void intf_Manage( intf_thread_t *p_intf );
 
 /*****************************************************************************
  * intf_Create: prepare interface before main loop
@@ -93,9 +69,6 @@ static int      ParseChannel    ( intf_channel_t *p_channel, char *psz_str );
 intf_thread_t* intf_Create( void )
 {
     intf_thread_t * p_intf;
-    typedef void    ( intf_getplugin_t ) ( intf_thread_t * p_intf );
-    int             i_index;
-    int             i_best_index = 0, i_best_score = 0;
 
     /* Allocate structure */
     p_intf = malloc( sizeof( intf_thread_t ) );
@@ -106,84 +79,80 @@ intf_thread_t* intf_Create( void )
         return( NULL );
     }
 
-    /* Get a suitable interface plugin */
-    for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
-    {
-        /* If there's a plugin in p_info ... */
-        if( p_main->p_bank->p_info[ i_index ] != NULL )
-        {
-            /* ... and if this plugin provides the functions we want ... */
-            if( p_main->p_bank->p_info[ i_index ]->intf_GetPlugin != NULL )
-            {
-                /* ... and if this plugin has a good score ... */
-                if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
-                {
-                    /* ... then take it */
-                    i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
-                    i_best_index = i_index;
-                }
-            }
-        }
-    }
+    /* Choose the best module */
+    p_intf->p_module = module_Need( p_main->p_bank,
+                                    MODULE_CAPABILITY_INTF, NULL );
 
-    if( i_best_score == 0 )
+    if( p_intf->p_module == NULL )
     {
+        intf_ErrMsg( "intf error: no suitable intf module" );
         free( p_intf );
-        intf_ErrMsg( "intf error: no suitable plugin" );
         return( NULL );
     }
 
-    /* Get the plugin functions */
-    ( (intf_getplugin_t *)
-      p_main->p_bank->p_info[ i_best_index ]->intf_GetPlugin )( p_intf );
+#define f p_intf->p_module->p_functions->intf.functions.intf
+    p_intf->pf_open       = f.pf_open;
+    p_intf->pf_close      = f.pf_close;
+    p_intf->pf_run        = f.pf_run;
+#undef f
+
+    /* Initialize callbacks */
+    p_intf->pf_manage     = intf_Manage;
 
     /* Initialize structure */
     p_intf->b_die =     0;
-    p_intf->p_vout =    NULL;
-    p_intf->p_input =   NULL;
-    p_intf->p_keys =    NULL;
 
-    /* Warning level initialisation */
-    p_intf->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR, INTF_WARNING_DEFAULT );
-    
-    /* Load channels - the pointer will be set to NULL on failure. The
-     * return value is ignored since the program can work without
-     * channels */
-    LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR, INTF_CHANNELS_DEFAULT ));
+    p_intf->p_input =       NULL;
+    p_intf->p_keys =        NULL;
+    p_intf->b_menu =        0;
+    p_intf->b_menu_change = 0;
 
-    /* Start interfaces */
-    p_intf->p_console = intf_ConsoleCreate();
-    if( p_intf->p_console == NULL )
-    {
-        intf_ErrMsg( "intf error: cannot create control console" );
-        free( p_intf );
-        return( NULL );
-    }
-
-    if( p_intf->p_sys_create( p_intf ) )
+    if( p_intf->pf_open( p_intf ) )
     {
         intf_ErrMsg("intf error: cannot create interface");
-        intf_ConsoleDestroy( p_intf->p_console );
+        module_Unneed( p_main->p_bank, p_intf->p_module );
         free( p_intf );
         return( NULL );
     }
 
+    /* Initialize mutexes */
+    vlc_mutex_init( &p_intf->change_lock );
+
+    /* Load channels - the pointer will be set to NULL on failure. The
+     * return value is ignored since the program can work without
+     * channels */
+    intf_LoadChannels( p_intf, main_GetPszVariable( INTF_CHANNELS_VAR,
+                                                    INTF_CHANNELS_DEFAULT ));
+
     intf_Msg("intf: interface initialized");
     return( p_intf );
 }
 
 /*****************************************************************************
- * intf_Run
+ * intf_Manage: manage interface
  *****************************************************************************
- * Initialization script and main interface loop.
+ * This function has to be called regularly by the interface plugin. It
+ * checks for playlist end, module expiration, message flushing, and a few
+ * other useful things.
  *****************************************************************************/
-void intf_Run( intf_thread_t *p_intf )
+static void intf_Manage( intf_thread_t *p_intf )
 {
-    /* Flush messages before spawning input */
+    /* Flush waiting messages */
     intf_FlushMsg();
 
-    /* Main loop */
-    while( !p_intf->b_die )
+    /* Manage module bank */
+    module_ManageBank( p_main->p_bank );
+
+    if( ( p_intf->p_input != NULL ) &&
+            ( p_intf->p_input->b_error || p_intf->p_input->b_eof ) )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+        p_intf->p_input = NULL;
+        intf_DbgMsg("Input thread destroyed");
+    }
+
+    /* If no stream is being played, try to find one */
+    if( p_intf->p_input == NULL && !p_intf->b_die )
     {
         /* Select the next playlist item */
         intf_PlstNext( p_main->p_playlist );
@@ -192,42 +161,11 @@ void intf_Run( intf_thread_t *p_intf )
         {
             /*    FIXME: wait for user to add stuff to playlist ? */
             p_intf->b_die = 1;
-            return;
         }
-
-        p_intf->p_input =
-                    input_CreateThread( &p_main->p_playlist->current, NULL );
-
-        /* Main loop */
-        while( !p_intf->b_die && (p_intf->p_input != NULL) )
+        else
         {
-            /* Flush waiting messages */
-            intf_FlushMsg();
-
-            /* Manage specific interface */
-            p_intf->p_sys_manage( p_intf );
-
-            /* Manage module bank */
-            module_ManageBank( p_main->p_module_bank );
-
-            /* Check attached threads status */
-            if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
-            {
-                /* FIXME: add aout error detection ?? */
-                p_intf->b_die = 1;
-            }
-
-            if( ( p_intf->p_input != NULL ) &&
-                    ( p_intf->p_input->b_error || p_intf->p_input->b_eof ) )
-            {
-                input_DestroyThread( p_intf->p_input, NULL );
-                p_intf->p_input = NULL;
-                intf_DbgMsg("Input thread destroyed");
-            }
-
-            /* Sleep to avoid using all CPU - since some interfaces needs
-             * to access keyboard events, a 100ms delay is a good compromise */
-            msleep( INTF_IDLE_SLEEP );
+            p_intf->p_input =
+                input_CreateThread( &p_main->p_playlist->current, NULL );
         }
     }
 }
@@ -241,12 +179,18 @@ void intf_Destroy( intf_thread_t *p_intf )
 {
     p_intf_key  p_cur;
     p_intf_key  p_next;
-    /* Destroy interfaces */
-    p_intf->p_sys_destroy( p_intf );
-    intf_ConsoleDestroy( p_intf->p_console );
 
     /* Unload channels */
-    UnloadChannels( p_intf );
+    intf_UnloadChannels( p_intf );
+
+    /* Destroy interfaces */
+    p_intf->pf_close( p_intf );
+
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {   
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
 
     /* Destroy keymap */
     p_cur = p_intf->p_keys;
@@ -257,54 +201,13 @@ void intf_Destroy( intf_thread_t *p_intf )
         p_cur = p_next;
     }
          
-    /* Free structure */
-    free( p_intf );
-}
+    /* Unlock module */
+    module_Unneed( p_main->p_bank, p_intf->p_module );
 
-/*****************************************************************************
- * intf_SelectChannel: change channel
- *****************************************************************************
- * Kill existing input, if any, and try to open a new one, using an input
- * configuration table.
- *****************************************************************************/
-int intf_SelectChannel( intf_thread_t * p_intf, int i_channel )
-{
-    /* FIXME */
-#if 0
-    intf_channel_t *    p_channel;                                /* channel */
-
-    /* Look for channel in array */
-    if( p_intf->p_channel != NULL )
-    {
-        for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ )
-        {
-            if( p_channel->i_channel == i_channel )
-            {
-            /*
-             * Change channel
-             */
-
-            /* Kill existing input, if any */
-            if( p_intf->p_input != NULL )
-            {
-                input_DestroyThread( p_intf->p_input, NULL );
-            }
-
-            intf_Msg("Channel %d: %s", i_channel, p_channel->psz_description );
-
-            /* Open a new input */
-            p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source,
-                                  p_channel->i_input_port, p_channel->i_input_vlan_id,
-                                  p_intf->p_vout, p_main->p_aout, NULL );
-            return( p_intf->p_input == NULL );
-            }
-        }
-    }
+    vlc_mutex_destroy( &p_intf->change_lock );
 
-    /* Channel does not exist */
-    intf_Msg("Channel %d does not exist", i_channel );
-#endif
-    return( 1 );
+    /* Free structure */
+    free( p_intf );
 }
 
 /*****************************************************************************
@@ -444,57 +347,21 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
             p_main->p_aout->vol = i_volbackup;
         break;
     case INTF_KEY_DEC_GAMMA:                                      /* gamma - */
-        if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
+        if( (p_main->p_vout != NULL) && (p_main->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
         {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->f_gamma   -= INTF_GAMMA_STEP;
-            p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+            vlc_mutex_lock( &p_main->p_vout->change_lock );
+            p_main->p_vout->f_gamma   -= INTF_GAMMA_STEP;
+            p_main->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
+            vlc_mutex_unlock( &p_main->p_vout->change_lock );
         }
         break;
     case INTF_KEY_INC_GAMMA:                                      /* gamma + */
-        if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
+        if( (p_main->p_vout != NULL) && (p_main->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
         {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->f_gamma   += INTF_GAMMA_STEP;
-            p_intf->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-        }
-        break;
-    case INTF_KEY_TOGGLE_GRAYSCALE:                      /* toggle grayscale */
-        if( p_intf->p_vout != NULL )
-        {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->b_grayscale = !p_intf->p_vout->b_grayscale;
-            p_intf->p_vout->i_changes  |= VOUT_GRAYSCALE_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-        }
-        break;
-    case INTF_KEY_TOGGLE_INTERFACE:                      /* toggle interface */
-        if( p_intf->p_vout != NULL )
-        {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->b_interface     = !p_intf->p_vout->b_interface;
-            p_intf->p_vout->i_changes |= VOUT_INTF_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-        }
-        break;
-    case INTF_KEY_TOGGLE_INFO:                                /* toggle info */
-        if( p_intf->p_vout != NULL )
-        {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->b_info     = !p_intf->p_vout->b_info;
-            p_intf->p_vout->i_changes |= VOUT_INFO_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
-        }
-        break;
-    case INTF_KEY_TOGGLE_SCALING:                          /* toggle scaling */
-        if( p_intf->p_vout != NULL )
-        {
-            vlc_mutex_lock( &p_intf->p_vout->change_lock );
-            p_intf->p_vout->b_scale    = !p_intf->p_vout->b_scale;
-            p_intf->p_vout->i_changes |= VOUT_SCALE_CHANGE;
-            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+            vlc_mutex_lock( &p_main->p_vout->change_lock );
+            p_main->p_vout->f_gamma   += INTF_GAMMA_STEP;
+            p_main->p_vout->i_changes |= VOUT_GAMMA_CHANGE;
+            vlc_mutex_unlock( &p_main->p_vout->change_lock );
         }
         break;
    default:                                                   /* unknown key */
@@ -504,243 +371,3 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
     return( 0 );
 }
 
-/* following functions are local */
-
-/*****************************************************************************
- * LoadChannels: load channels description from a file
- *****************************************************************************
- * This structe describes all interface-specific data of the main (interface)
- * thread.
- * Each line of the file is a semicolon separated list of the following
- * fields :
- *      integer         channel number
- *      string          channel description
- *      integer         input method (see input.h)
- *      string          input source
- *      integer         input port
- *      integer         input vlan id
- * The last field must end with a semicolon.
- * Comments and empty lines are not explicitely allowed, but lines with parsing
- * errors are ignored without warning.
- *****************************************************************************/
-static int LoadChannels( intf_thread_t *p_intf, char *psz_filename )
-{
-    FILE *              p_file;                                      /* file */
-    intf_channel_t *    p_channel;                        /* current channel */
-    char                psz_line[INTF_MAX_CMD_SIZE];          /* line buffer */
-    int                 i_index;                   /* channel or field index */
-
-    /* Set default value */
-    p_intf->p_channel = NULL;
-
-    /* FIXME: channels are disabled */
-    //return( 0 );
-
-    /* Open file */
-    p_file = fopen( psz_filename, "r" );
-    if( p_file == NULL )
-    {
-        intf_DbgMsg( "intf warning: cannot open %s (%s)",
-                     psz_filename, strerror(errno) );
-        return( 1 );
-    }
-
-    /* First pass: count number of lines */
-    for( i_index = 0; fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL; i_index++ )
-    {
-        ;
-    }
-
-    if( i_index != 0 )
-    {
-        /* Allocate array and rewind - some of the lines may be invalid, and the
-         * array will probably be larger than the actual number of channels, but
-         * it has no consequence. */
-        p_intf->p_channel = malloc( sizeof( intf_channel_t ) * i_index );
-        if( p_intf->p_channel == NULL )
-        {
-            intf_ErrMsg( "intf error: cannot create intf_channel_t (%s)",
-                         strerror(ENOMEM) );
-            fclose( p_file );
-            return( 1 );
-        }
-        p_channel = p_intf->p_channel;
-        rewind( p_file );
-
-        /* Second pass: read channels descriptions */
-        while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL )
-        {
-            if( !ParseChannel( p_channel, psz_line ) )
-            {
-                intf_DbgMsg( "channel [%d] %s : method %d (%s:%d vlan id %d)",
-                         p_channel->i_channel, p_channel->psz_description,
-                         p_channel->i_input_method,
-                         p_channel->psz_input_source,
-                         p_channel->i_input_port, p_channel->i_input_vlan_id );
-                p_channel++;
-            }
-        }
-
-        /* Add marker at the end of the array */
-        p_channel->i_channel = -1;
-    }
-
-    /* Close file */
-    fclose( p_file );
-    return( 0 );
-}
-
-/*****************************************************************************
- * UnloadChannels: unload channels description
- *****************************************************************************
- * This function free all resources allocated by LoadChannels, if any.
- *****************************************************************************/
-static void UnloadChannels( intf_thread_t *p_intf )
-{
-    int i_channel;                                          /* channel index */
-
-    if( p_intf->p_channel != NULL )
-    {
-        /* Free allocated strings */
-        for( i_channel = 0;
-             p_intf->p_channel[ i_channel ].i_channel != -1;
-             i_channel++ )
-        {
-            if( p_intf->p_channel[ i_channel ].psz_description != NULL )
-            {
-                free( p_intf->p_channel[ i_channel ].psz_description );
-            }
-            if( p_intf->p_channel[ i_channel ].psz_input_source != NULL )
-            {
-                free( p_intf->p_channel[ i_channel ].psz_input_source );
-            }
-        }
-
-        /* Free array */
-        free( p_intf->p_channel );
-        p_intf->p_channel = NULL;
-    }
-}
-
-
-/*****************************************************************************
- * ParseChannel: parse a channel description line
- *****************************************************************************
- * See LoadChannels. This function return non 0 on parsing error.
- *****************************************************************************/
-static int ParseChannel( intf_channel_t *p_channel, char *psz_str )
-{
-    char *      psz_index;                              /* current character */
-    char *      psz_end;                           /* end pointer for strtol */
-    int         i_field;                        /* field number, -1 on error */
-    int         i_field_length;             /* field length, for text fields */
-
-    /* Set some default fields */
-    p_channel->i_channel =              0;
-    p_channel->psz_description =        NULL;
-    p_channel->i_input_method =         0;
-    p_channel->psz_input_source =       NULL;
-    p_channel->i_input_port =           0;
-    p_channel->i_input_vlan_id =        0;
-
-    /* Parse string */
-    i_field = 0;
-    for( psz_index = psz_str; (i_field != -1) && (*psz_index != '\0'); psz_index++ )
-    {
-        if( *psz_index == ';' )
-        {
-            /* Mark end of field */
-            *psz_index = '\0';
-
-            /* Parse field */
-            switch( i_field++ )
-            {
-            case 0:                                        /* channel number */
-                p_channel->i_channel = strtol( psz_str, &psz_end, 0);
-                if( (*psz_str == '\0') || (*psz_end != '\0') )
-                {
-                    i_field = -1;
-                }
-                break;
-            case 1:                                   /* channel description */
-                i_field_length = strlen( psz_str );
-                if( i_field_length != 0 )
-                {
-                    p_channel->psz_description = malloc( i_field_length + 1 );
-                    if( p_channel->psz_description == NULL )
-                    {
-                        intf_ErrMsg( "intf error: cannot create channel "
-                                     "description (%s)", strerror( ENOMEM ) );
-                        i_field = -1;
-                    }
-                    else
-                    {
-                        strcpy( p_channel->psz_description, psz_str );
-                    }
-                }
-                break;
-            case 2:                                          /* input method */
-                p_channel->i_input_method = strtol( psz_str, &psz_end, 0);
-                if( (*psz_str == '\0') || (*psz_end != '\0') )
-                {
-                    i_field = -1;
-                }
-                break;
-            case 3:                                          /* input source */
-                i_field_length = strlen( psz_str );
-                if( i_field_length != 0 )
-                {
-                    p_channel->psz_input_source = malloc( i_field_length + 1 );
-                    if( p_channel->psz_input_source == NULL )
-                    {
-                        intf_ErrMsg( "intf error: cannot create input "
-                                     "source (%s)", strerror( ENOMEM ) );
-                        i_field = -1;
-                    }
-                    else
-                    {
-                        strcpy( p_channel->psz_input_source, psz_str );
-                    }
-                }
-                break;
-            case 4:                                            /* input port */
-                p_channel->i_input_port = strtol( psz_str, &psz_end, 0);
-                if( (*psz_str == '\0') || (*psz_end != '\0') )
-                {
-                    i_field = -1;
-                }
-                break;
-            case 5:                                          /* input vlan id */
-                p_channel->i_input_vlan_id = strtol( psz_str, &psz_end, 0);
-                if( (*psz_str == '\0') || (*psz_end != '\0') )
-                {
-                    i_field = -1;
-                }
-                break;
-                /* ... following fields are ignored */
-            }
-
-            /* Set new beginning of field */
-            psz_str = psz_index + 1;
-        }
-    }
-
-    /* At least the first three fields must be parsed sucessfully for function
-     * success. Other parsing errors are returned using i_field = -1. */
-    if( i_field < 3 )
-    {
-        /* Function fails. Free allocated strings */
-        if( p_channel->psz_description != NULL )
-        {
-            free( p_channel->psz_description );
-        }
-        if( p_channel->psz_input_source != NULL )
-        {
-            free( p_channel->psz_input_source );
-        }
-        return( 1 );
-    }
-
-    /* Return success */
-    return( 0 );
-}
diff --git a/src/interface/intf_channels.c b/src/interface/intf_channels.c
new file mode 100644
index 0000000000000000000000000000000000000000..f6ad68111a0407122683844ca792c7d5a31059b3
--- /dev/null
+++ b/src/interface/intf_channels.c
@@ -0,0 +1,332 @@
+/*****************************************************************************
+ * intf_channels.c: channel handling functions
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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 "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                      /* free(), strtol() */
+#include <stdio.h>                                                   /* FILE */
+#include <string.h>                                            /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+
+#include "intf_msg.h"
+#include "intf_channels.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int ParseChannel( intf_channel_t *p_channel, char *psz_str );
+
+/*****************************************************************************
+ * intf_LoadChannels: load channels description from a file
+ *****************************************************************************
+ * This structe describes all interface-specific data of the main (interface)
+ * thread.
+ * Each line of the file is a semicolon separated list of the following
+ * fields :
+ *      integer         channel number
+ *      string          channel description
+ *      integer         input method (see input.h)
+ *      string          input source
+ *      integer         input port
+ *      integer         input vlan id
+ * The last field must end with a semicolon.
+ * Comments and empty lines are not explicitely allowed, but lines with parsing
+ * errors are ignored without warning.
+ *****************************************************************************/
+int intf_LoadChannels( intf_thread_t *p_intf, char *psz_filename )
+{
+    FILE *              p_file;                                      /* file */
+    intf_channel_t *    p_channel;                        /* current channel */
+    char                psz_line[INTF_MAX_CMD_SIZE];          /* line buffer */
+    int                 i_index;                   /* channel or field index */
+
+    /* Set default value */
+    p_intf->p_channel = NULL;
+
+    /* Open file */
+    p_file = fopen( psz_filename, "r" );
+    if( p_file == NULL )
+    {
+        intf_DbgMsg( "intf warning: cannot open %s (%s)",
+                     psz_filename, strerror(errno) );
+        return( 1 );
+    }
+
+    /* First pass: count number of lines */
+    for( i_index = 0; fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL;
+         i_index++ )
+    {
+        ;
+    }
+
+    if( i_index != 0 )
+    {
+        /* Allocate array and rewind - some of the lines may be invalid, and the
+         * array will probably be larger than the actual number of channels, but
+         * it has no consequence. */
+        p_intf->p_channel = malloc( sizeof( intf_channel_t ) * i_index );
+        if( p_intf->p_channel == NULL )
+        {
+            intf_ErrMsg( "intf error: cannot create intf_channel_t (%s)",
+                         strerror(ENOMEM) );
+            fclose( p_file );
+            return( 1 );
+        }
+        p_channel = p_intf->p_channel;
+        rewind( p_file );
+
+        /* Second pass: read channels descriptions */
+        while( fgets( psz_line, INTF_MAX_CMD_SIZE, p_file ) != NULL )
+        {
+            if( !ParseChannel( p_channel, psz_line ) )
+            {
+                intf_DbgMsg( "channel [%d] %s : method %d (%s:%d vlan id %d)",
+                         p_channel->i_channel, p_channel->psz_description,
+                         p_channel->i_input_method,
+                         p_channel->psz_input_source,
+                         p_channel->i_input_port, p_channel->i_input_vlan_id );
+                p_channel++;
+            }
+        }
+
+        /* Add marker at the end of the array */
+        p_channel->i_channel = -1;
+    }
+
+    /* Close file */
+    fclose( p_file );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_UnloadChannels: unload channels description
+ *****************************************************************************
+ * This function free all resources allocated by LoadChannels, if any.
+ *****************************************************************************/
+void intf_UnloadChannels( intf_thread_t *p_intf )
+{
+    int i_channel;                                          /* channel index */
+
+    if( p_intf->p_channel != NULL )
+    {
+        /* Free allocated strings */
+        for( i_channel = 0;
+             p_intf->p_channel[ i_channel ].i_channel != -1;
+             i_channel++ )
+        {
+            if( p_intf->p_channel[ i_channel ].psz_description != NULL )
+            {
+                free( p_intf->p_channel[ i_channel ].psz_description );
+            }
+            if( p_intf->p_channel[ i_channel ].psz_input_source != NULL )
+            {
+                free( p_intf->p_channel[ i_channel ].psz_input_source );
+            }
+        }
+
+        /* Free array */
+        free( p_intf->p_channel );
+        p_intf->p_channel = NULL;
+    }
+}
+
+/*****************************************************************************
+ * intf_SelectChannel: change channel
+ *****************************************************************************
+ * Kill existing input, if any, and try to open a new one, using an input
+ * configuration table.
+ *****************************************************************************/
+int intf_SelectChannel( intf_thread_t * p_intf, int i_channel )
+{
+    /* FIXME */
+#if 0
+    intf_channel_t *    p_channel;                                /* channel */
+
+    /* Look for channel in array */
+    if( p_intf->p_channel != NULL )
+    {
+        for( p_channel = p_intf->p_channel; p_channel->i_channel != -1; p_channel++ )
+        {
+            if( p_channel->i_channel == i_channel )
+            {
+            /*
+             * Change channel
+             */
+
+            /* Kill existing input, if any */
+            if( p_intf->p_input != NULL )
+            {
+                input_DestroyThread( p_intf->p_input, NULL );
+            }
+
+            intf_Msg("Channel %d: %s", i_channel, p_channel->psz_description );
+
+            /* Open a new input */
+            p_intf->p_input = input_CreateThread( p_channel->i_input_method, p_channel->psz_input_source,
+                                  p_channel->i_input_port, p_channel->i_input_vlan_id,
+                                  p_intf->p_vout, p_main->p_aout, NULL );
+            return( p_intf->p_input == NULL );
+            }
+        }
+    }
+
+    /* Channel does not exist */
+    intf_Msg("Channel %d does not exist", i_channel );
+#endif
+    return( 1 );
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * ParseChannel: parse a channel description line
+ *****************************************************************************
+ * See intf_LoadChannels. This function return non 0 on parsing error.
+ *****************************************************************************/
+static int ParseChannel( intf_channel_t *p_channel, char *psz_str )
+{
+    char *      psz_index;                              /* current character */
+    char *      psz_end;                           /* end pointer for strtol */
+    int         i_field;                        /* field number, -1 on error */
+    int         i_field_length;             /* field length, for text fields */
+
+    /* Set some default fields */
+    p_channel->i_channel =              0;
+    p_channel->psz_description =        NULL;
+    p_channel->i_input_method =         0;
+    p_channel->psz_input_source =       NULL;
+    p_channel->i_input_port =           0;
+    p_channel->i_input_vlan_id =        0;
+
+    /* Parse string */
+    i_field = 0;
+    for( psz_index = psz_str; (i_field != -1) && (*psz_index != '\0'); psz_index++ )
+    {
+        if( *psz_index == ';' )
+        {
+            /* Mark end of field */
+            *psz_index = '\0';
+
+            /* Parse field */
+            switch( i_field++ )
+            {
+            case 0:                                        /* channel number */
+                p_channel->i_channel = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;
+            case 1:                                   /* channel description */
+                i_field_length = strlen( psz_str );
+                if( i_field_length != 0 )
+                {
+                    p_channel->psz_description = malloc( i_field_length + 1 );
+                    if( p_channel->psz_description == NULL )
+                    {
+                        intf_ErrMsg( "intf error: cannot create channel "
+                                     "description (%s)", strerror( ENOMEM ) );
+                        i_field = -1;
+                    }
+                    else
+                    {
+                        strcpy( p_channel->psz_description, psz_str );
+                    }
+                }
+                break;
+            case 2:                                          /* input method */
+                p_channel->i_input_method = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;
+            case 3:                                          /* input source */
+                i_field_length = strlen( psz_str );
+                if( i_field_length != 0 )
+                {
+                    p_channel->psz_input_source = malloc( i_field_length + 1 );
+                    if( p_channel->psz_input_source == NULL )
+                    {
+                        intf_ErrMsg( "intf error: cannot create input "
+                                     "source (%s)", strerror( ENOMEM ) );
+                        i_field = -1;
+                    }
+                    else
+                    {
+                        strcpy( p_channel->psz_input_source, psz_str );
+                    }
+                }
+                break;
+            case 4:                                            /* input port */
+                p_channel->i_input_port = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;
+            case 5:                                          /* input vlan id */
+                p_channel->i_input_vlan_id = strtol( psz_str, &psz_end, 0);
+                if( (*psz_str == '\0') || (*psz_end != '\0') )
+                {
+                    i_field = -1;
+                }
+                break;
+                /* ... following fields are ignored */
+            }
+
+            /* Set new beginning of field */
+            psz_str = psz_index + 1;
+        }
+    }
+
+    /* At least the first three fields must be parsed sucessfully for function
+     * success. Other parsing errors are returned using i_field = -1. */
+    if( i_field < 3 )
+    {
+        /* Function fails. Free allocated strings */
+        if( p_channel->psz_description != NULL )
+        {
+            free( p_channel->psz_description );
+        }
+        if( p_channel->psz_input_source != NULL )
+        {
+            free( p_channel->psz_input_source );
+        }
+        return( 1 );
+    }
+
+    /* Return success */
+    return( 0 );
+}
+
diff --git a/src/interface/intf_channels.h b/src/interface/intf_channels.h
new file mode 100644
index 0000000000000000000000000000000000000000..133101b01f11fb9038c15f354a3f8d1c3209828e
--- /dev/null
+++ b/src/interface/intf_channels.h
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * intf_channels.h: Channel handling functions
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * intf_channel_t: channel description
+ *****************************************************************************
+ * A 'channel' is a descriptor of an input method. It is used to switch easily
+ * from source to source without having to specify the whole input thread
+ * configuration. The channels array, stored in the interface thread object, is
+ * loaded in intf_Create, and unloaded in intf_Destroy.
+ *****************************************************************************/
+typedef struct intf_channel_s
+{
+    /* Channel description */
+    int         i_channel;            /* channel number, -1 for end of array */
+    char *      psz_description;              /* channel description (owned) */
+
+    /* Input configuration */
+    int         i_input_method;                   /* input method descriptor */
+    char *      psz_input_source;                   /* source string (owned) */
+    int         i_input_port;                                        /* port */
+    int         i_input_vlan_id;                                  /* vlan id */
+} intf_channel_t;
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+int     intf_LoadChannels   ( struct intf_thread_s *, char * );
+void    intf_UnloadChannels ( struct intf_thread_s * );
+int     intf_SelectChannel  ( struct intf_thread_s *, int );
+
diff --git a/src/interface/intf_cmd.c b/src/interface/intf_cmd.c
index 7f1262d08f554f6a638b168415c26ef403d9dcee..7d1302d6e7975b84837377d3d7202ecdaa2c601c 100644
--- a/src/interface/intf_cmd.c
+++ b/src/interface/intf_cmd.c
@@ -37,7 +37,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "interface.h"
 #include "intf_msg.h"
diff --git a/src/interface/intf_ctrl.c b/src/interface/intf_ctrl.c
index 723f88664b8a66b73239122ea14cf223a3925fcd..d6e21e911167b01da9dde822b976ff5b93c5487c 100644
--- a/src/interface/intf_ctrl.c
+++ b/src/interface/intf_ctrl.c
@@ -54,7 +54,6 @@
 #include "threads.h"
 #include "mtime.h"
 #include "debug.h"
-#include "plugins.h"
 #include "intf_msg.h"
 
 #include "stream_control.h"
diff --git a/src/interface/intf_msg.c b/src/interface/intf_msg.c
index 9a8d709012254beff498537df9af2f8d6a2ed3d0..64e454b8d19e02d51cc1b27c9ed3cb04a212265d 100644
--- a/src/interface/intf_msg.c
+++ b/src/interface/intf_msg.c
@@ -39,7 +39,7 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
+
 #include "intf_msg.h"
 #include "interface.h"
 #include "intf_console.h"
@@ -224,7 +224,7 @@ void intf_WarnMsg( int i_level, char *psz_format, ... )
 {
     va_list ap;
     
-    if( i_level >= p_main->p_intf->i_warning_level )
+    if( i_level >= p_main->i_warning_level )
     {
         va_start( ap, psz_format );
         QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap );
@@ -316,7 +316,7 @@ void intf_WarnMsgImm( int i_level, char *psz_format, ... )
 {
     va_list ap;
 
-    if( i_level >= p_main->p_intf->i_warning_level )
+    if( i_level >= p_main->i_warning_level )
     {
         va_start( ap, psz_format );
         QueueMsg( p_main->p_msg, INTF_MSG_WARN, psz_format, ap );
diff --git a/src/interface/intf_plst.c b/src/interface/intf_plst.c
index 36292d1432ec5c57959941fb791fc80bff7810f3..69c5c16a668be64ba08cb517a40f3391ec95ff96 100644
--- a/src/interface/intf_plst.c
+++ b/src/interface/intf_plst.c
@@ -85,7 +85,7 @@ void intf_PlstInit ( playlist_t * p_playlist )
     /* The playlist is empty */
     p_playlist->p_item = NULL;
 
-    intf_Msg("intf: playlist initialized");
+    intf_WarnMsg( 1, "intf: playlist initialized" );
 }
 
 /*****************************************************************************
@@ -235,7 +235,7 @@ void intf_PlstDestroy( playlist_t * p_playlist )
 
     free( p_playlist );
 
-    intf_Msg("intf: playlist destroyed");
+    intf_WarnMsg( 1, "intf: playlist destroyed" );
 }
 
 /*****************************************************************************
diff --git a/src/interface/main.c b/src/interface/main.c
index 8a5de7439d4dfcc14d2e8fb48c7be1b5d76ef5de..7cba67b8fafbd3ba8bb6035256650002fd22fc0a 100644
--- a/src/interface/main.c
+++ b/src/interface/main.c
@@ -44,8 +44,8 @@
 #include "threads.h"
 #include "mtime.h"
 #include "tests.h"                                              /* TestCPU() */
-#include "plugins.h"
 #include "modules.h"
+
 #include "stream_control.h"
 #include "input_ext-intf.h"
 
@@ -55,6 +55,9 @@
 
 #include "audio_output.h"
 
+#include "video.h"
+#include "video_output.h"
+
 #ifdef SYS_BEOS
 #include "beos_specific.h"
 #endif
@@ -167,6 +170,7 @@ main_t *p_main;
 static void SetDefaultConfiguration ( void );
 static int  GetConfiguration        ( int i_argc, char *ppsz_argv[],
                                       char *ppsz_env[] );
+static int  GetFilenames            ( int i_argc, char *ppsz_argv[] );
 static void Usage                   ( int i_fashion );
 static void Version                 ( void );
 
@@ -198,15 +202,15 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
 #endif
 
     p_main->i_cpu_capabilities = CPUCapabilities();
-
+    
     /*
      * Test if our code is likely to run on this CPU 
      */
 #if defined( __pentium__ ) || defined( __pentiumpro__ )
     if( ! TestCPU( CPU_CAPABILITY_586 ) )
     {
-        fprintf( stderr, "Sorry, this program needs a Pentium CPU.\n"
-                         "Please try a version without Pentium support.\n" );
+        fprintf( stderr, "error: this program needs a Pentium CPU,\n"
+                         "please try a version without Pentium support\n" );
         return( 1 );
     }
 #endif
@@ -214,8 +218,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
 #ifdef HAVE_MMX
     if( ! TestCPU( CPU_CAPABILITY_MMX ) )
     {
-        fprintf( stderr, "Sorry, this program needs MMX extensions.\n"
-                         "Please try a version without MMX support.\n" );
+        fprintf( stderr, "error: this program needs MMX extensions,\n"
+                         "please try a version without MMX support\n" );
         return( 1 );
     }
 #endif
@@ -234,52 +238,46 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     intf_MsgImm( COPYRIGHT_MESSAGE );
 
     /*
-     * Initialize playlist and get commandline files
+     * Read configuration
      */
-    p_main->p_playlist = intf_PlstCreate( );
-    if( !p_main->p_playlist )
+    if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
     {
-        intf_ErrMsg( "playlist error: playlist initialization failed" );
         intf_MsgDestroy();
         return( errno );
     }
-    intf_PlstInit( p_main->p_playlist );
+
+    p_main->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR,
+                                                   INTF_WARNING_DEFAULT );
 
     /*
-     * Read configuration
+     * Initialize playlist and get commandline files
      */
-    if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
+    p_main->p_playlist = intf_PlstCreate( );
+    if( !p_main->p_playlist )
     {
+        intf_ErrMsg( "playlist error: playlist initialization failed" );
         intf_MsgDestroy();
         return( errno );
     }
+    intf_PlstInit( p_main->p_playlist );
 
     /*
-     * Initialize plugin bank
+     * Get input filenames given as commandline arguments
      */
-    p_main->p_bank = bank_Create( );
-    if( !p_main->p_bank )
-    {
-        intf_ErrMsg( "plugin error: plugin bank initialization failed" );
-        intf_PlstDestroy( p_main->p_playlist );
-        intf_MsgDestroy();
-        return( errno );
-    }
-    bank_Init( p_main->p_bank );
+    GetFilenames( i_argc, ppsz_argv );
 
     /*
      * Initialize module bank
      */
-    p_main->p_module_bank = module_CreateBank( );
-    if( !p_main->p_module_bank )
+    p_main->p_bank = module_CreateBank( );
+    if( !p_main->p_bank )
     {
         intf_ErrMsg( "module error: module bank initialization failed" );
-        bank_Destroy( p_main->p_bank );
         intf_PlstDestroy( p_main->p_playlist );
         intf_MsgDestroy();
         return( errno );
     }
-    module_InitBank( p_main->p_module_bank );
+    module_InitBank( p_main->p_bank );
 
     /*
      * Initialize shared resources and libraries
@@ -299,45 +297,76 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
      * Run interface
      */
     p_main->p_intf = intf_Create();
+    if( !p_main->p_intf )
+    {
+        intf_ErrMsg( "intf error: interface initialization failed" );
+        module_DestroyBank( p_main->p_bank );
+        intf_PlstDestroy( p_main->p_playlist );
+        intf_MsgDestroy();
+        return( errno );
+    }
 
-    if( p_main->p_intf != NULL )
+    /*
+     * Set signal handling policy for all threads
+     */
+    InitSignalHandler();
+
+    /*
+     * Open audio device and start aout thread
+     */
+    if( p_main->b_audio )
     {
-        /*
-         * Set signal handling policy for all threads
-         */
-        InitSignalHandler();
-
-        /*
-         * Open audio device and start aout thread
-         */
-        if( p_main->b_audio )
+        p_main->p_aout = aout_CreateThread( NULL );
+        if( p_main->p_aout == NULL )
         {
-            p_main->p_aout = aout_CreateThread( NULL );
-            if( p_main->p_aout == NULL )
-            {
-                /* On error during audio initialization, switch off audio */
-                intf_ErrMsg( "aout error: audio initialization failed,"
-                             " audio is deactivated" );
-                p_main->b_audio = 0;
-            }
+            /* On error during audio initialization, switch off audio */
+            intf_ErrMsg( "aout error: audio initialization failed,"
+                         " audio is deactivated" );
+            p_main->b_audio = 0;
         }
+    }
 
-        /*
-         * This is the main loop
-         */
-        intf_Run( p_main->p_intf );
-
-        intf_Destroy( p_main->p_intf );
-
-        /*
-         * Close audio device
-         */
-        if( p_main->b_audio )
+    /*
+     * Open video device and start aout thread
+     */
+    if( p_main->b_video )
+    {
+        p_main->p_vout = vout_CreateThread( NULL );
+        if( p_main->p_vout == NULL )
         {
-            aout_DestroyThread( p_main->p_aout, NULL );
+            /* On error during video initialization, switch off audio */
+            intf_ErrMsg( "vout error: video initialization failed,"
+                         " video is deactivated" );
+            p_main->b_video = 0;
         }
     }
 
+    /* Flush messages before entering the main loop */
+    intf_FlushMsg();
+
+    /*
+     * This is the main loop
+     */
+    p_main->p_intf->pf_run( p_main->p_intf );
+
+    intf_Destroy( p_main->p_intf );
+
+    /*
+     * Close video device
+     */
+    if( p_main->b_video )
+    {
+        vout_DestroyThread( p_main->p_vout, NULL );
+    }
+
+    /*
+     * Close audio device
+     */
+    if( p_main->b_audio )
+    {
+        aout_DestroyThread( p_main->p_aout, NULL );
+    }
+
     /*
      * Free shared resources and libraries
      */
@@ -352,12 +381,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     /*
      * Free module bank
      */
-    module_DestroyBank( p_main->p_module_bank );
-
-    /*
-     * Free plugin bank
-     */
-    bank_Destroy( p_main->p_bank );
+    module_DestroyBank( p_main->p_bank );
 
     /*
      * Free playlist
@@ -374,7 +398,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     /*
      * Terminate messages interface and program
      */
-    intf_Msg( "intf: program terminated." );
+    intf_Msg( "intf: program terminated" );
     intf_MsgDestroy();
 
     return( 0 );
@@ -493,7 +517,7 @@ static void SetDefaultConfiguration( void )
  *****************************************************************************/
 static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
 {
-    int c, i_opt;
+    int c;
     char * p_pointer;
 
     /* Set default configuration and copy arguments */
@@ -644,6 +668,17 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
         }
     }
 #endif
+    return( 0 );
+}
+
+/*****************************************************************************
+ * GetFilenames: parse command line options which are not flags
+ *****************************************************************************
+ * Parse command line for input files.
+ *****************************************************************************/
+static int GetFilenames( int i_argc, char *ppsz_argv[] )
+{
+    int i_opt;
 
     /* We assume that the remaining parameters are filenames */
     for( i_opt = optind; i_opt < i_argc; i_opt++ )
@@ -798,7 +833,7 @@ static void InitSignalHandler( void )
 static void SimpleSignalHandler( int i_signal )
 {
     /* Acknowledge the signal received */
-    intf_WarnMsg(0, "intf: ignoring signal %d", i_signal );
+    intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
 }
 
 
@@ -810,15 +845,15 @@ static void SimpleSignalHandler( int i_signal )
  *****************************************************************************/
 static void FatalSignalHandler( int i_signal )
 {
-    /* Once a signal has been trapped, the termination sequence will be armed and
-     * following signals will be ignored to avoid sending messages to an interface
-     * having been destroyed */
+    /* Once a signal has been trapped, the termination sequence will be
+     * armed and following signals will be ignored to avoid sending messages
+     * to an interface having been destroyed */
     signal( SIGHUP,  SIG_IGN );
     signal( SIGINT,  SIG_IGN );
     signal( SIGQUIT, SIG_IGN );
 
     /* Acknowledge the signal received */
-    intf_ErrMsgImm("intf error: signal %d received, exiting", i_signal );
+    intf_ErrMsgImm( "intf error: signal %d received, exiting", i_signal );
 
     /* Try to terminate everything - this is done by requesting the end of the
      * interface thread */
diff --git a/src/lpcm_decoder/lpcm_decoder.c b/src/lpcm_decoder/lpcm_decoder.c
index dd8cdcb8ca40432009abb59bfbafce8a8ec69271..754d21a9a953f719a0dbe2b979178e0a6fa1c693 100644
--- a/src/lpcm_decoder/lpcm_decoder.c
+++ b/src/lpcm_decoder/lpcm_decoder.c
@@ -26,7 +26,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/lpcm_decoder/lpcm_decoder_thread.c b/src/lpcm_decoder/lpcm_decoder_thread.c
index 8104b50a844303180ea8bd005d59dee502bc6951..75af82c6e7c0c5ad24e23a139d4f326e64c47192 100644
--- a/src/lpcm_decoder/lpcm_decoder_thread.c
+++ b/src/lpcm_decoder/lpcm_decoder_thread.c
@@ -2,7 +2,7 @@
  * lpcm_decoder_thread.c: lpcm decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: lpcm_decoder_thread.c,v 1.9 2001/01/05 18:46:44 massiot Exp $
+ * $Id: lpcm_decoder_thread.c,v 1.10 2001/02/11 01:15:11 sam Exp $
  *
  * Authors:
  *
@@ -35,7 +35,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
 
diff --git a/src/misc/modules.c b/src/misc/modules.c
index 475ecd3feb48f5a07213d420a3a43d8216b7dcb2..9fe25ed9b8629132c559a84d1efbfc7ef3bc5591 100644
--- a/src/misc/modules.c
+++ b/src/misc/modules.c
@@ -95,7 +95,7 @@ void module_InitBank( module_bank_t * p_bank )
     p_bank->first = NULL;
     vlc_mutex_init( &p_bank->lock );
 
-    intf_Msg( "module: module bank initialized" );
+    intf_WarnMsg( 1, "module: module bank initialized" );
 
     for( ; *ppsz_path != NULL ; ppsz_path++ )
     {
@@ -308,7 +308,11 @@ module_t * module_Need( module_bank_t *p_bank,
     /* We release the global lock */
     vlc_mutex_unlock( &p_bank->lock );
 
-    intf_WarnMsg( 1, "module: locking module `%s'", p_bestmodule->psz_name );
+    if( p_bestmodule != NULL )
+    {
+        intf_WarnMsg( 1, "module: locking module `%s'",
+                      p_bestmodule->psz_name );
+    }
 
     /* Don't forget that the module is still locked if bestmodule != NULL */
     return( p_bestmodule );
@@ -357,8 +361,8 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename )
     if( module_load( psz_filename, &handle ) )
     {
         /* The dynamic module couldn't be opened */
-        intf_ErrMsg( "module warning: cannot open %s (%s)",
-                     psz_filename, module_error() );
+        intf_WarnMsgImm( 1, "module warning: cannot open %s (%s)",
+                         psz_filename, module_error() );
         return( -1 );
     }
 
diff --git a/src/misc/plugins.c b/src/misc/plugins.c
deleted file mode 100644
index 8f44a374eba6fb50919fee4d153498a0115ca1e1..0000000000000000000000000000000000000000
--- a/src/misc/plugins.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*****************************************************************************
- * plugins.c : Dynamic plugin management functions
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * 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.
- *****************************************************************************/
-#include "defs.h"
-
-#include "config.h"
-
-#include <stdlib.h>                                      /* free(), strtol() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-#include <errno.h>                                                 /* ENOMEM */
-#include <sys/types.h>                                               /* open */
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>                                                 /* close */
-
-#if defined(HAVE_DLFCN_H)                                /* Linux, BSD, Hurd */
-#include <dlfcn.h>                           /* dlopen(), dlsym(), dlclose() */
-
-#elif defined(HAVE_IMAGE_H)                                          /* BeOS */
-#include <image.h>
-
-#else
-#error no dynamic plugins available on your system !
-#endif
-
-#ifdef SYS_BEOS
-#include "beos_specific.h"
-#endif
-
-#include "common.h"
-
-#include "intf_msg.h"
-#include "plugins.h"
-
-/* Local prototypes */
-char * TestPlugin     ( plugin_id_t *p_plugin_id, char * psz_name );
-int    AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank,
-                        char * psz_filename );
-
-plugin_bank_t * bank_Create( void )
-{
-    plugin_bank_t *p_bank;
-    int i;
-
-    /* Allocate structure */
-    p_bank = malloc( sizeof( plugin_bank_t ) );
-    if( !p_bank )
-    {
-        intf_ErrMsg("plugin error: failed to create bank (%s)", strerror( ENOMEM ) );
-        return( NULL );
-    }
-
-    /* Initialize structure */
-    for( i = 0 ; i < MAX_PLUGIN_COUNT ; i++ )
-    {
-        p_bank->p_info[ i ] = NULL;
-    }
-    p_bank->i_plugin_count = MAX_PLUGIN_COUNT;
-
-    return( p_bank );
-}
-
-void bank_Init( plugin_bank_t * p_bank )
-{
-    plugin_id_t tmp;
-    char * psz_filename;
-
-    /* FIXME: we should browse all directories to get plugins */
-#define SEEK_PLUGIN( name ) \
-    psz_filename = TestPlugin( &tmp, name ); \
-    if( psz_filename ) AllocatePlugin( tmp, p_bank, psz_filename );
-
-    /* Arch plugins */
-    SEEK_PLUGIN( "beos" );
-
-    /* Low level Video */
-    SEEK_PLUGIN( "x11" );
-    SEEK_PLUGIN( "fb" );
-    SEEK_PLUGIN( "glide" );
-    SEEK_PLUGIN( "mga" );
-     
-    /* High level Video */
-    SEEK_PLUGIN( "gnome" );
-    SEEK_PLUGIN( "ggi" );
-    SEEK_PLUGIN( "sdl" );
-   
-    /* Dummy plugin */
-    SEEK_PLUGIN( "dummy" );
-#undef SEEK_PLUGIN
-
-    intf_Msg("plugin: plugin bank initialized [OBSOLETE]");
-}
-
-void bank_Destroy( plugin_bank_t * p_bank )
-{
-    int i;
-    for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
-    {
-        if( p_bank->p_info[ i ] != NULL )
-        {
-            free( p_bank->p_info[ i ]-> psz_filename );
-        }
-    }
-
-    free( p_bank );
-}
-
-/*
- * Following functions are local
- */
-
-char * TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name )
-{
-    int i_count, i_length, i_fd;
-    char * psz_plugin;
-    char * psz_plugin_path[ ] =
-    {
-        ".",
-        "lib", /* this one should disappear */
-        PLUGIN_PATH,
-        NULL
-    };
-
-    i_length = strlen( psz_name );
-
-    for ( i_count = 0 ; psz_plugin_path[ i_count ] ; i_count++ )
-    {
-#ifdef SYS_BEOS
-        char * psz_program_path;
-        
-        psz_program_path = beos_GetProgramPath();
-        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
-                             strlen(psz_program_path) + i_length + 6 );
-        sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
-                 psz_plugin_path[i_count], psz_name );        
-
-        *p_plugin_id = load_add_on( psz_plugin );
-#else
-        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
-        sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
-
-        /* Try to open the plugin before dlopen()ing it. */
-        i_fd = open( psz_plugin, O_RDONLY );
-        if( i_fd == -1 )
-        {
-            free( psz_plugin );
-            continue;
-        }
-        close( i_fd );
-        
-        *p_plugin_id = dlopen( psz_plugin, RTLD_NOW );
-#endif
-
-#ifdef SYS_BEOS
-        if( *p_plugin_id >= 0 )
-#else
-        if( *p_plugin_id != NULL )
-#endif
-        {
-            /* plugin successfuly dlopened */
-            return( psz_plugin );
-        }
-
-#ifndef SYS_BEOS
-        intf_ErrMsg( "plugin error: cannot open %s (%s)", psz_plugin, dlerror() );
-#endif
-
-        free( psz_plugin );
-    }
-
-    return( NULL );
-}
-
-
-int AllocatePlugin( plugin_id_t plugin_id, plugin_bank_t * p_bank,
-                    char * psz_filename )
-{
-    typedef plugin_info_t * ( get_config_t ) ( void );
-    get_config_t * p_func;   
-    int i;
-
-    for( i = 0 ; i < p_bank->i_plugin_count ; i++ )
-    {
-        if( p_bank->p_info[ i ] == NULL )
-        {
-            break;
-        }
-    }
-
-    /* no room to store that plugin, quit */
-    if( i == p_bank->i_plugin_count )
-    {
-        intf_ErrMsg( "plugin bank error: reached max plugin count (%i), "
-                     "increase MAX_PLUGIN_COUNT", p_bank->i_plugin_count );
-        return( -1 );
-    }
-
-    /* system-specific dynamic symbol loading */
-    GET_PLUGIN( p_func, plugin_id, "GetConfig" );
-
-    /* if it failed, just quit */
-    if( !p_func )
-    {
-        return( -1 );
-    }
-
-    /* run the plugin function to initialize the structure */
-    p_bank->p_info[ i ]            = p_func( );
-    p_bank->p_info[ i ]->plugin_id = plugin_id;
-    p_bank->p_info[ i ]->psz_filename = strdup( psz_filename );
-
-
-    /* Tell the world we found it */
-    intf_Msg( "plugin: #%i, %s %s (score 0x%x)", i,
-              p_bank->p_info[ i ]->psz_name,
-              p_bank->p_info[ i ]->psz_version,
-              p_bank->p_info[ i ]->i_score );
-
-    /* return nicely */
-    return( 0 );
-}
-
-#if 0
-void TrashPlugin ( plugin_id_t plugin_id )
-{
-#ifdef SYS_BEOS
-    unload_add_on( plugin_id );
-#else
-    dlclose( plugin_id );
-#endif
-}
-#endif
-
diff --git a/src/spu_decoder/spu_decoder.c b/src/spu_decoder/spu_decoder.c
index 692d81301e018b3b3db9963c83f8333e47e99647..b7e7109c1b9392b623f1544b5b8b1695accd3f2b 100644
--- a/src/spu_decoder/spu_decoder.c
+++ b/src/spu_decoder/spu_decoder.c
@@ -32,7 +32,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 #include "debug.h"                                                 /* ASSERT */
diff --git a/src/video_decoder/video_decoder.c b/src/video_decoder/video_decoder.c
index e14c23f2c685dc33ef5b9ac14e7f73ce59ce1860..8215925ba3c0e4195c401a4095e74ca705a7ce27 100644
--- a/src/video_decoder/video_decoder.c
+++ b/src/video_decoder/video_decoder.c
@@ -2,7 +2,7 @@
  * video_decoder.c : video decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_decoder.c,v 1.45 2001/01/18 05:13:23 sam Exp $
+ * $Id: video_decoder.c,v 1.46 2001/02/11 01:15:11 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Ga�l Hendryckx <jimmy@via.ecp.fr>
@@ -35,7 +35,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 64203da143b016db226725d17625847c5ae62cbc..2ddf26675fd02fdf277357d4c19863d11ea0ac5d 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -41,7 +41,8 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
+#include "modules.h"
+
 #include "video.h"
 #include "video_output.h"
 #include "video_text.h"
@@ -49,6 +50,7 @@
 #include "video_yuv.h"
 
 #include "intf_msg.h"
+
 #include "main.h"
 
 /*****************************************************************************
@@ -90,15 +92,11 @@ static void     SetPalette        ( p_vout_thread_t p_vout, u16 *red,
  * If pi_status is NULL, then the function will block until the thread is ready.
  * If not, it will be updated using one of the THREAD_* constants.
  *****************************************************************************/
-vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
-                          int i_width, int i_height, int *pi_status,
-                          int i_method, void *p_data )
+vout_thread_t * vout_CreateThread   ( int *pi_status )
 {
     vout_thread_t * p_vout;                             /* thread descriptor */
-    typedef void    ( vout_getplugin_t ) ( vout_thread_t * p_vout );
     int             i_status;                               /* thread status */
     int             i_index;               /* index for array initialization */
-    int             i_best_index = 0, i_best_score = 0;
 
     /* Allocate descriptor */
     p_vout = (vout_thread_t *) malloc( sizeof(vout_thread_t) );
@@ -109,37 +107,31 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
         return( NULL );
     }
 
-    p_vout->p_set_palette       = SetPalette;
+    /* Choose the best module */
+    p_vout->p_module = module_Need( p_main->p_bank,
+                                    MODULE_CAPABILITY_VOUT, NULL );
 
-    /* Get a suitable video plugin */
-    for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
-    {
-        /* If there's a plugin in p_info ... */
-        if( p_main->p_bank->p_info[ i_index ] != NULL )
-        {
-            /* ... and if this plugin provides the functions we want ... */
-            if( p_main->p_bank->p_info[ i_index ]->vout_GetPlugin != NULL )
-            {
-                /* ... and if this plugin has a good score ... */
-                if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
-                {
-                    /* ... then take it */
-                    i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
-                    i_best_index = i_index;
-                }
-            }
-        }
-    }
-
-    if( i_best_score == 0 )
+    if( p_vout->p_module == NULL )
     {
+        intf_ErrMsg( "vout error: no suitable vout module" );
         free( p_vout );
         return( NULL );
     }
 
-    /* Get the plugin functions */
-    ( (vout_getplugin_t *)
-      p_main->p_bank->p_info[ i_best_index ]->vout_GetPlugin )( p_vout );
+#define f p_vout->p_module->p_functions->vout.functions.vout
+    p_vout->pf_create     = f.pf_create;
+    p_vout->pf_init       = f.pf_init;
+    p_vout->pf_end        = f.pf_end;
+    p_vout->pf_destroy    = f.pf_destroy;
+    p_vout->pf_manage     = f.pf_manage;
+    p_vout->pf_display    = f.pf_display;
+    p_vout->pf_setpalette = f.pf_setpalette;
+#undef f
+
+    if( p_vout->pf_setpalette == NULL )
+    {
+        p_vout->pf_setpalette = SetPalette;
+    }
 
     /* Initialize thread properties - thread id and locks will be initialized
      * later */
@@ -153,16 +145,18 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
      * fields will probably be modified by the method, and are only
      * preferences */
     p_vout->i_changes             = 0;
-    p_vout->i_width               = i_width;
-    p_vout->i_height              = i_height;
-    p_vout->i_bytes_per_line      = i_width * 2;
+    p_vout->i_width               = main_GetIntVariable( VOUT_WIDTH_VAR,
+                                                         VOUT_WIDTH_DEFAULT );
+    p_vout->i_height              = main_GetIntVariable( VOUT_HEIGHT_VAR,
+                                                         VOUT_HEIGHT_DEFAULT );
+    p_vout->i_bytes_per_line      = p_vout->i_width * 2;
     p_vout->i_screen_depth        = 15;
     p_vout->i_bytes_per_pixel     = 2;
     p_vout->f_gamma               = VOUT_GAMMA;
     p_vout->b_need_render         = 1;
 
     p_vout->b_grayscale           = main_GetIntVariable( VOUT_GRAYSCALE_VAR,
-                                                       VOUT_GRAYSCALE_DEFAULT );
+                                                     VOUT_GRAYSCALE_DEFAULT );
     p_vout->b_info                = 0;
     p_vout->b_interface           = 0;
     p_vout->b_scale               = 1;
@@ -199,8 +193,9 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
 
     /* Create and initialize system-dependant method - this function issues its
      * own error messages */
-    if( p_vout->p_sys_create( p_vout, psz_display, i_root_window, p_data ) )
+    if( p_vout->pf_create( p_vout ) )
     {
+        module_Unneed( p_main->p_bank, p_vout->p_module );
         free( p_vout );
         return( NULL );
     }
@@ -235,7 +230,7 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
     if( p_vout->p_default_font == NULL )
     {
         intf_ErrMsg( "vout error: could not load default font" );
-        p_vout->p_sys_destroy( p_vout );
+        p_vout->pf_destroy( p_vout );
         free( p_vout );
         return( NULL );
     }
@@ -248,7 +243,7 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
     {
         intf_ErrMsg( "vout error: could not load large font" );
         vout_UnloadFont( p_vout->p_default_font );
-        p_vout->p_sys_destroy( p_vout );
+        p_vout->pf_destroy( p_vout );
         free( p_vout );
         return( NULL );
     }
@@ -264,7 +259,7 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
         intf_ErrMsg("vout error: %s", strerror(ENOMEM));
         vout_UnloadFont( p_vout->p_default_font );
         vout_UnloadFont( p_vout->p_large_font );
-        p_vout->p_sys_destroy( p_vout );
+        p_vout->pf_destroy( p_vout );
         free( p_vout );
         return( NULL );
     }
@@ -930,7 +925,7 @@ static int InitThread( vout_thread_t *p_vout )
 #endif
 
    /* Initialize output method - this function issues its own error messages */
-    if( p_vout->p_sys_init( p_vout ) )
+    if( p_vout->pf_init( p_vout ) )
     {
         return( 1 );
     }
@@ -1191,7 +1186,7 @@ static void RunThread( vout_thread_t *p_vout)
 #endif
         if( b_display /* && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) */ )
         {
-            p_vout->p_sys_display( p_vout );
+            p_vout->pf_display( p_vout );
 #ifndef SYS_BEOS
             p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
 #endif
@@ -1217,7 +1212,7 @@ static void RunThread( vout_thread_t *p_vout)
         /*
          * Check events and manage thread
          */
-        if( p_vout->p_sys_manage( p_vout ) | Manage( p_vout ) )
+        if( p_vout->pf_manage( p_vout ) | Manage( p_vout ) )
         {
             /* A fatal error occured, and the thread must terminate immediately,
              * without displaying anything - setting b_error to 1 cause the
@@ -1299,7 +1294,7 @@ static void EndThread( vout_thread_t *p_vout )
 
     /* Destroy translation tables */
     vout_EndYUV( p_vout );
-    p_vout->p_sys_end( p_vout );
+    p_vout->pf_end( p_vout );
 
     /* Release the change lock */
     vlc_mutex_unlock( &p_vout->change_lock );
@@ -1321,13 +1316,16 @@ static void DestroyThread( vout_thread_t *p_vout, int i_status )
     /* Destroy thread structures allocated by Create and InitThread */
     vout_UnloadFont( p_vout->p_default_font );
     vout_UnloadFont( p_vout->p_large_font );
-    p_vout->p_sys_destroy( p_vout );
+    p_vout->pf_destroy( p_vout );
 
     /* Destroy the locks */
     vlc_mutex_destroy( &p_vout->picture_lock );
     vlc_mutex_destroy( &p_vout->subpicture_lock );
     vlc_mutex_destroy( &p_vout->change_lock );
                 
+    /* Release the module */
+    module_Unneed( p_main->p_bank, p_vout->p_module );
+
     /* Free structure */
     free( p_vout );
     *pi_status = i_status;
@@ -2076,7 +2074,7 @@ static int Manage( vout_thread_t *p_vout )
     /* Detect unauthorized changes */
     if( p_vout->i_changes )
     {
-        /* Some changes were not acknowledged by p_vout->p_sys_manage or this
+        /* Some changes were not acknowledged by p_vout->pf_manage or this
          * function, it means they should not be authorized */
         intf_ErrMsg( "vout error: unauthorized changes in the vout thread" );
         return( 1 );
diff --git a/src/video_output/video_spu.c b/src/video_output/video_spu.c
index 6a6fd83bac41533a5e21b591651cae8db0c6f6be..bc9aa9c9b71e996f1da16cca3f2cf88869fb9ec3 100644
--- a/src/video_output/video_spu.c
+++ b/src/video_output/video_spu.c
@@ -32,8 +32,8 @@
 #include "config.h"
 #include "common.h"
 #include "threads.h"
-#include "plugins.h"
 #include "mtime.h"
+
 #include "video.h"
 #include "video_output.h"
 #include "video_spu.h"
diff --git a/src/video_output/video_yuv.c b/src/video_output/video_yuv.c
index 432d89e1c35d05f1452849d7cd11b93f6a341f51..0b0a95486db534ebf92565c3f1ed87102d0c5b13 100644
--- a/src/video_output/video_yuv.c
+++ b/src/video_output/video_yuv.c
@@ -55,7 +55,7 @@
 int vout_InitYUV( vout_thread_t *p_vout )
 {
     /* Choose the best module */
-    p_vout->yuv.p_module = module_Need( p_main->p_module_bank,
+    p_vout->yuv.p_module = module_Need( p_main->p_bank,
                                         MODULE_CAPABILITY_YUV, NULL );
 
     if( p_vout->yuv.p_module == NULL )
@@ -93,6 +93,6 @@ int vout_ResetYUV( vout_thread_t *p_vout )
 void vout_EndYUV( vout_thread_t *p_vout )
 {
     p_vout->yuv.pf_end( p_vout );
-    module_Unneed( p_main->p_module_bank, p_vout->yuv.p_module );
+    module_Unneed( p_main->p_bank, p_vout->yuv.p_module );
 }
 
diff --git a/src/video_parser/video_fifo.c b/src/video_parser/video_fifo.c
index c42aa1647b0ce9fa947aaded43768efa328393f0..1de3967595aabc778f4fea2e372465fb5badd905 100644
--- a/src/video_parser/video_fifo.c
+++ b/src/video_parser/video_fifo.c
@@ -2,7 +2,7 @@
  * video_fifo.c : video FIFO management
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_fifo.c,v 1.28 2001/01/18 05:13:23 sam Exp $
+ * $Id: video_fifo.c,v 1.29 2001/02/11 01:15:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -30,7 +30,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c
index 417f48c6ab29cbf7d5228748b493b6f2d196361a..60ee50213948beb4ccb37d13a3786b4aa7206d83 100644
--- a/src/video_parser/video_parser.c
+++ b/src/video_parser/video_parser.c
@@ -2,7 +2,7 @@
  * video_parser.c : video parser thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_parser.c,v 1.72 2001/02/08 17:44:13 massiot Exp $
+ * $Id: video_parser.c,v 1.73 2001/02/11 01:15:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -40,7 +40,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 #include "modules.h"
 
 #include "intf_msg.h"
@@ -104,7 +103,7 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config )
     /*
      * Choose the best motion compensation module
      */
-    p_vpar->p_motion_module = module_Need( p_main->p_module_bank,
+    p_vpar->p_motion_module = module_Need( p_main->p_bank,
                                            MODULE_CAPABILITY_MOTION, NULL );
 
     if( p_vpar->p_motion_module == NULL )
@@ -170,13 +169,13 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config )
      /*
       * Choose the best IDCT module
       */
-    p_vpar->p_idct_module = module_Need( p_main->p_module_bank,
+    p_vpar->p_idct_module = module_Need( p_main->p_bank,
                                          MODULE_CAPABILITY_IDCT, NULL );
 
     if( p_vpar->p_idct_module == NULL )
     {
         intf_ErrMsg( "vpar error: no suitable IDCT module" );
-        module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module );
+        module_Unneed( p_main->p_bank, p_vpar->p_motion_module );
         free( p_vpar );
         return( 0 );
     }
@@ -193,8 +192,8 @@ vlc_thread_t vpar_CreateThread( vdec_config_t * p_config )
                             (vlc_thread_func_t)RunThread, (void *)p_vpar ) )
     {
         intf_ErrMsg("vpar error: can't spawn video parser thread");
-        module_Unneed( p_main->p_module_bank, p_vpar->p_idct_module );
-        module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module );
+        module_Unneed( p_main->p_bank, p_vpar->p_idct_module );
+        module_Unneed( p_main->p_bank, p_vpar->p_motion_module );
         free( p_vpar );
         return( 0 );
     }
@@ -511,8 +510,8 @@ static void EndThread( vpar_thread_t *p_vpar )
     
     vlc_mutex_destroy( &(p_vpar->synchro.fifo_lock) );
     
-    module_Unneed( p_main->p_module_bank, p_vpar->p_idct_module );
-    module_Unneed( p_main->p_module_bank, p_vpar->p_motion_module );
+    module_Unneed( p_main->p_bank, p_vpar->p_idct_module );
+    module_Unneed( p_main->p_bank, p_vpar->p_motion_module );
 
     free( p_vpar );
 
diff --git a/src/video_parser/vpar_blocks.c b/src/video_parser/vpar_blocks.c
index df772cb603a07b2f1142a22135206fcf9b6d2cb4..e4e723bd6f9f783643cf8c297c9a08d98b941f20 100644
--- a/src/video_parser/vpar_blocks.c
+++ b/src/video_parser/vpar_blocks.c
@@ -2,7 +2,7 @@
  * vpar_blocks.c : blocks parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_blocks.c,v 1.74 2001/01/26 14:47:16 massiot Exp $
+ * $Id: vpar_blocks.c,v 1.75 2001/02/11 01:15:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Jean-Marc Dressler <polux@via.ecp.fr>
@@ -34,7 +34,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c
index c93da0a4fb20b84fa130a41225f81fc70d5e6942..e32a0b73867698dbacd919beff1d2dbefb05a05a 100644
--- a/src/video_parser/vpar_headers.c
+++ b/src/video_parser/vpar_headers.c
@@ -2,7 +2,7 @@
  * vpar_headers.c : headers parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.76 2001/02/06 17:17:04 massiot Exp $
+ * $Id: vpar_headers.c,v 1.77 2001/02/11 01:15:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          St�phane Borel <stef@via.ecp.fr>
@@ -33,7 +33,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c
index 5e2c8aa1d75d19d9e0047b429dcb7c1c789a1874..14ddc8db3b4ea6ce4d8516a083d93e24d53f7d06 100644
--- a/src/video_parser/vpar_synchro.c
+++ b/src/video_parser/vpar_synchro.c
@@ -2,7 +2,7 @@
  * vpar_synchro.c : frame dropping routines
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.80 2001/01/24 19:05:55 massiot Exp $
+ * $Id: vpar_synchro.c,v 1.81 2001/02/11 01:15:12 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -100,7 +100,6 @@
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"