* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.29 2001/03/16 22:37:06 massiot Exp $
+ * $Id: common.h,v 1.30 2001/04/11 02:01:24 henri Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
/* Input */
struct input_thread_s;
-struct input_vlan_s;
+struct input_channel_s;
struct input_cfg_s;
typedef struct input_thread_s * p_input_thread_t;
-typedef struct input_vlan_s * p_input_vlan_t;
+typedef struct input_channel_s * p_input_channel_t;
typedef struct input_cfg_s * p_input_cfg_t;
/* Audio */
#define INPUT_BROADCAST_DEFAULT 0
/*
- * Vlan method
+ * Channel method
*/
/* Default network interface and environment variable */
#define INPUT_IFACE_DEFAULT "eth0"
/* Default server and port */
-#define INPUT_VLAN_SERVER_VAR "vlc_vlan_server"
-#define INPUT_VLAN_SERVER_DEFAULT "138.195.139.95"
-#define INPUT_VLAN_PORT_VAR "vlc_vlan_port"
-#define INPUT_VLAN_PORT_DEFAULT 6010
-
-/* Delay between vlan changes - this is required to avoid flooding the VLAN
- * server */
-#define INPUT_VLAN_CHANGE_DELAY (mtime_t)(5*CLOCK_FREQ)
+#define INPUT_CHANNEL_SERVER_VAR "vlc_channel_server"
+#define INPUT_CHANNEL_SERVER_DEFAULT "138.195.139.95"
+#define INPUT_CHANNEL_PORT_VAR "vlc_channel_port"
+#define INPUT_CHANNEL_PORT_DEFAULT 6010
+
+/* Delay between channel changes - this is required to avoid flooding the
+ * channel server */
+#define INPUT_CHANNEL_CHANGE_DELAY (mtime_t)(5*CLOCK_FREQ)
/* Duration between the time we receive the data packet, and the time we will
* mark it to be presented */
* Declaration and extern access to global program object.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: main.h,v 1.14 2001/03/21 13:42:33 sam Exp $
+ * $Id: main.h,v 1.15 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
/* Generic settings */
boolean_t b_audio; /* is audio output allowed ? */
boolean_t b_video; /* is video output allowed ? */
- boolean_t b_vlans; /* are vlans supported ? */
+ boolean_t b_channels; /* is channel changing supported ? */
boolean_t b_dvd; /* DVD mode ? */
/* Unique threads */
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 */
+ p_input_channel_t p_channel; /* channel library data */
} main_t;
extern main_t *p_main;
* modules.
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: netutils.h,v 1.9 2001/03/21 13:42:33 sam Exp $
+ * $Id: netutils.h,v 1.10 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Henri Fallon <henri@videolan.org>
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+/* The channel without stream is 0 */
+#define COMMON_CHANNEL 0
+
/*****************************************************************************
* Prototypes
*****************************************************************************/
int network_BuildLocalAddr ( struct sockaddr_in *, int, boolean_t );
int network_BuildRemoteAddr( struct sockaddr_in *, char * );
-
+int network_ChannelJoin( int i_channel_id );
+int network_ChannelCreate( void );
* vout_sdl.c: SDL video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vout_sdl.c,v 1.46 2001/04/06 09:15:47 sam Exp $
+ * $Id: vout_sdl.c,v 1.47 2001/04/11 02:01:24 henri Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Pierre Baillet <oct@zoy.org>
/* FIXME: get rid of this */
#include "keystrokes.h"
#include "main.h"
+#include "netutils.h"
/*****************************************************************************
* FIXME: this file is ... *
static int vout_Manage( vout_thread_t *p_vout )
{
SDL_Event event; /* SDL event */
- Uint8 i_key;
+ char * p_key;
/* Process events */
while( SDL_PollEvent(&event) )
break;
case SDL_KEYDOWN: /* if a key is pressed */
- i_key = event.key.keysym.sym;
- switch( i_key )
+ switch( event.key.keysym.sym )
{
case SDLK_f: /* switch to fullscreen */
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
p_vout->b_interface = ! p_vout->b_interface;
p_vout->i_changes |= VOUT_INTF_CHANGE;
break;
+
+ case SDLK_F10:
+ network_ChannelJoin( 0 );
+ break;
+ case SDLK_F1:
+ network_ChannelJoin( 1 );
+ break;
+ case SDLK_F2:
+ network_ChannelJoin( 2 );
+ break;
+ case SDLK_F3:
+ network_ChannelJoin( 3 );
+ break;
+ case SDLK_F4:
+ network_ChannelJoin( 4 );
+ break;
+ case SDLK_F5:
+ network_ChannelJoin( 5 );
+ break;
+ case SDLK_F6:
+ network_ChannelJoin( 6 );
+ break;
+ case SDLK_F7:
+ network_ChannelJoin( 7 );
+ break;
+ case SDLK_F8:
+ network_ChannelJoin( 8 );
+ break;
+ case SDLK_F9:
+ network_ChannelJoin( 9 );
+ break;
+ case SDLK_MENU:
+ p_main->p_intf->b_menu_change = 1;
+ break;
+
default:
- if( intf_ProcessKey( p_main->p_intf, (char )i_key ) )
+ p_key = SDL_GetKeyName( event.key.keysym.sym ) ;
+ if( intf_ProcessKey( p_main->p_intf,
+ (char )event.key.keysym.sym ) )
{
- intf_DbgMsg( "unhandled key '%c' (%i)", (char)i_key, i_key ); }
+ intf_DbgMsg( "unhandled key '%c' (%i)",
+ (char)event.key.keysym.sym,
+ event.key.keysym.sym );
+ }
break;
}
break;
* vout_x11.c: X11 video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vout_x11.c,v 1.17 2001/04/01 06:21:44 sam Exp $
+ * $Id: vout_x11.c,v 1.18 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
#include "interface.h"
#include "intf_msg.h"
+#include "netutils.h" /* network_ChannelJoin */
+
#include "main.h"
/*****************************************************************************
int i_ss_blanking; /* blanking mode */
int i_ss_exposure; /* exposure mode */
+ /* Auto-hide cursor */
+ mtime_t i_lastmoved;
+
/* Mouse pointer properties */
boolean_t b_mouse; /* is the mouse pointer displayed ? */
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 );
+
+ /* Set date for autohiding cursor */
+ p_vout->p_sys->i_lastmoved = mdate();
+
return( 0 );
}
XEvent xevent; /* X11 event */
boolean_t b_resized; /* window has been resized */
char i_key; /* ISO Latin-1 key */
+ KeySym x_key_symbol;
+
/* Handle X11 events: ConfigureNotify events are parsed to know if the
* output window's size changed, MapNotify and UnmapNotify to know if the
b_resized = 0;
while( XCheckWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask, &xevent )
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | Button1MotionMask , &xevent )
== True )
{
/* ConfigureNotify event: prepare */
/* Keyboard event */
else if( xevent.type == KeyPress )
{
- if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+ /* We may have keys like F1 trough F12, ESC ... */
+ x_key_symbol = XKeycodeToKeysym( p_vout->p_sys->p_display,
+ xevent.xkey.keycode, 0 );
+ switch( x_key_symbol )
{
- /* FIXME: handle stuff here */
- switch( i_key )
- {
- case 'q':
- /* FIXME: need locking ! */
- p_main->p_intf->b_die = 1;
- break;
- }
+ case XK_Escape:
+ p_main->p_intf->b_die = 1;
+ break;
+ case XK_Menu:
+ p_main->p_intf->b_menu_change = 1;
+ break;
+ default:
+ /* "Normal Keys"
+ * The reason why I use this instead of XK_0 is that
+ * with XLookupString, we don't have to care about
+ * keymaps. */
+
+ if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+ {
+ /* FIXME: handle stuff here */
+ switch( i_key )
+ {
+ case 'q':
+ case 'Q':
+ p_main->p_intf->b_die = 1;
+ break;
+ case '0':
+ network_ChannelJoin( 0 );
+ break;
+ case '1':
+ network_ChannelJoin( 1 );
+ break;
+ case '2':
+ network_ChannelJoin( 2 );
+ break;
+ case '3':
+ network_ChannelJoin( 3 );
+ break;
+ case '4':
+ network_ChannelJoin( 4 );
+ break;
+ case '5':
+ network_ChannelJoin( 5 );
+ break;
+ case '6':
+ network_ChannelJoin( 6 );
+ break;
+ case '7':
+ network_ChannelJoin( 7 );
+ break;
+ case '8':
+ network_ChannelJoin( 8 );
+ break;
+ case '9':
+ network_ChannelJoin( 9 );
+ 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;
}
}
/* Mouse click */
/* in this part we will eventually manage
* clicks for DVD navigation for instance */
break;
-
- case Button2:
- X11TogglePointer( p_vout );
- break;
}
}
/* Mouse release */
break;
}
}
+ /* Mouse move */
+ else if( xevent.type == MotionNotify )
+ {
+ p_vout->p_sys->i_lastmoved = mdate();
+ if( ! p_vout->p_sys->b_mouse )
+ {
+ X11TogglePointer( p_vout );
+ }
+ }
#ifdef DEBUG
/* Other event */
else
p_vout->i_width, p_vout->i_height);
}
+ /* Autohide Cursour */
+ if( mdate() - p_vout->p_sys->i_lastmoved > 2000000 )
+ {
+ /* Hide the mouse automatically */
+ if( p_vout->p_sys->b_mouse )
+ {
+ X11TogglePointer( p_vout );
+ }
+ }
+
+
return 0;
}
XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask );
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask );
if( XDefaultDepth(p_vout->p_sys->p_display, p_vout->p_sys->i_screen) == 8 )
{
* vout_xvideo.c: Xvideo video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
- * $Id: vout_xvideo.c,v 1.4 2001/04/08 16:57:47 sam Exp $
+ * $Id: vout_xvideo.c,v 1.5 2001/04/11 02:01:24 henri Exp $
*
* Authors: Shane Harper <shanegh@optusnet.com.au>
* Vincent Seguin <seguin@via.ecp.fr>
#include "interface.h"
#include "intf_msg.h"
+#include "netutils.h" /* network_ChannelJoin */
+
#include "main.h"
/*****************************************************************************
int i_ss_interval; /* interval between changes */
int i_ss_blanking; /* blanking mode */
int i_ss_exposure; /* exposure mode */
-
+
+ /* Auto-hide cursor */
+ mtime_t i_lastmoved;
+
/* Mouse pointer properties */
boolean_t b_mouse; /* is the mouse pointer displayed ? */
XEvent xevent; /* X11 event */
boolean_t b_resized; /* window has been resized */
char i_key; /* ISO Latin-1 key */
+ KeySym x_key_symbol;
/* Handle X11 events: ConfigureNotify events are parsed to know if the
* output window's size changed, MapNotify and UnmapNotify to know if the
b_resized = 0;
while( XCheckWindowEvent( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask, &xevent )
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask, &xevent )
== True )
{
/* ConfigureNotify event: prepare */
/* Keyboard event */
else if( xevent.type == KeyPress )
{
- if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+ /* We may have keys like F1 trough F12, ESC ... */
+ x_key_symbol = XKeycodeToKeysym( p_vout->p_sys->p_display,
+ xevent.xkey.keycode, 0 );
+ switch( x_key_symbol )
{
- /* FIXME: handle stuff here */
- switch( i_key )
- {
- case 'q':
- /* FIXME: need locking ! */
- p_main->p_intf->b_die = 1;
- break;
- }
+ case XK_Escape:
+ p_main->p_intf->b_die = 1;
+ break;
+ case XK_Menu:
+ p_main->p_intf->b_menu_change = 1;
+ break;
+ default:
+ /* "Normal Keys"
+ * The reason why I use this instead of XK_0 is that
+ * with XLookupString, we don't have to care about
+ * keymaps. */
+
+ if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+ {
+ /* FIXME: handle stuff here */
+ switch( i_key )
+ {
+ case 'q':
+ case 'Q':
+ p_main->p_intf->b_die = 1;
+ break;
+ case '0':
+ network_ChannelJoin( 0 );
+ break;
+ case '1':
+ network_ChannelJoin( 1 );
+ break;
+ case '2':
+ network_ChannelJoin( 2 );
+ break;
+ case '3':
+ network_ChannelJoin( 3 );
+ break;
+ case '4':
+ network_ChannelJoin( 4 );
+ break;
+ case '5':
+ network_ChannelJoin( 5 );
+ break;
+ case '6':
+ network_ChannelJoin( 6 );
+ break;
+ case '7':
+ network_ChannelJoin( 7 );
+ break;
+ case '8':
+ network_ChannelJoin( 8 );
+ break;
+ case '9':
+ network_ChannelJoin( 9 );
+ 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;
}
}
/* Mouse click */
/* in this part we will eventually manage
* clicks for DVD navigation for instance */
break;
-
- case Button2:
- XVideoTogglePointer( p_vout );
- break;
}
}
/* Mouse release */
break;
}
}
+ /* Mouse move */
+ else if( xevent.type == MotionNotify )
+ {
+ p_vout->p_sys->i_lastmoved = mdate();
+ if( ! p_vout->p_sys->b_mouse )
+ {
+ XVideoTogglePointer( p_vout );
+ }
+ }
+
#ifdef DEBUG
/* Other event */
else
p_vout->i_width, p_vout->i_height );
}
+ /* Autohide Cursour */
+ if( mdate() - p_vout->p_sys->i_lastmoved > 2000000 )
+ {
+ /* Hide the mouse automatically */
+ if( p_vout->p_sys->b_mouse )
+ {
+ XVideoTogglePointer( p_vout );
+ }
+ }
+
return 0;
}
XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask );
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask );
/* At this stage, the window is open, displayed, and ready to
* receive data */
* interface, such as command line.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: interface.c,v 1.71 2001/03/21 13:42:34 sam Exp $
+ * $Id: interface.c,v 1.72 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
keyparm k_reply;
k_reply = intf_GetKey( p_intf, g_key);
-
switch( k_reply.key )
{
- case INTF_KEY_QUIT: /* quit order */
+ case INTF_KEY_QUIT: /* quit order */
p_intf->b_die = 1;
break;
case INTF_KEY_SET_CHANNEL:
/* Change channel - return code is ignored since SelectChannel displays
* its own error messages */
- intf_SelectChannel( p_intf, k_reply.param );
+/* intf_SelectChannel( p_intf, k_reply.param ); */
+/* network_ChannelJoin() */
+/* FIXME : keyboard event is for the time being half handled by the interface
+ * half handled directly by the plugins. We should decide what to do. */
break;
case INTF_KEY_INC_VOLUME: /* volume + */
if( (p_main->p_aout != NULL) && (p_main->p_aout->vol < VOLUME_MAX) )
return( 0 );
}
-
* More informations about parameters stand in `list of commands' section.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_ctrl.c,v 1.35 2001/04/06 09:15:47 sam Exp $
+ * $Id: intf_ctrl.c,v 1.36 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
#ifdef DEBUG
static int Test ( int i_argc, intf_arg_t *p_argv );
#endif
-static int Vlan ( int i_argc, intf_arg_t *p_argv );
+static int Channel ( int i_argc, intf_arg_t *p_argv );
static int Psi ( int i_argc, intf_arg_t *p_argv );
/*
/* help: */ "Spawn a decoder thread for <pid>. The stream will be" \
" received by <input>." },
{ "spawn-input", SpawnInput, /* spawn-input */
- /* format: */ "method=i? filename=s? hostname=s? ip=s? port=i? vlan=i?",
+ /* format: */ "method=i? filename=s? hostname=s? ip=s? port=i?"\
+ " channel=i?",
/* summary: */ "spawn an input thread",
/* summary: */ "spawn-input [method=<method>]\n" \
"[filename=<file>|hostname=<hostname>|ip=<ip>]\n" \
- "[port=<port>] [vlan=<vlan>]",
+ "[port=<port>] [channel=<channel>]",
/* help: */ "Spawn an input thread. Method is 10, 20, 21, 22, 32, "\
"hostname is the fully-qualified domain name, ip is a dotted-decimal address." },
#ifdef DEBUG
"developpers as an easy way to test part of their code. If you don't know "\
"what it should do, just try !" },
#endif
- { "vlan", Vlan,
+ { "channel", Channel,
/* format: */ "intf=s? s i? ",
- /* summary: */ "vlan operations",
- /* usage: */ "vlan synchro\n" \
- "vlan [intf=<interface>] request\n" \
- "vlan [intf=<interface>] join <vlan>\n" \
- "vlan [intf=<interface>] leave",
- /* help: */ "Perform various operations on vlans. 'synchro' resynchronize " \
- "with the server. 'request' ask which is the current vlan (for the default "\
- "interface or for a given one). 'join' and 'leave' try to change vlan." },
+ /* summary: */ "channel changing operations",
+ /* usage: */ "channel synchro\n" \
+ "channel [intf=<interface>] request\n" \
+ "channel [intf=<interface>] join <channel>\n" \
+ "channel [intf=<interface>] leave",
+ /* help: */ "Perform various operations on channels. 'synchro'"\
+ "resynchronize with the server. 'request' ask which is the current"\
+ "channel (for the default interface or for a given one)."\
+ "'join' and 'leave' try to change channel." },
{ "psi", Psi,
/* format: */ "i ",
/* summary: */ "Dump PSI tables",
#endif
/*****************************************************************************
- * Vlan: vlan operations
+ * Channels: channel operations
*****************************************************************************
- * This function performs various vlan operations.
+ * This function performs various channel operations.
*****************************************************************************/
-static int Vlan( int i_argc, intf_arg_t *p_argv )
+static int Channel( int i_argc, intf_arg_t *p_argv )
{
int i_command; /* command argument number */
- /* Do not try anything if vlans are deactivated */
- if( !p_main->b_vlans )
+ /* Do not try anything if channel changing is desactivated */
+ if( !p_main->b_channels )
{
- intf_IntfMsg("vlans are deactivated");
+ intf_IntfMsg("channel changing is desactivated");
return( INTF_OTHER_ERROR );
}
/* Command is unknown */
else
{
- intf_IntfMsg("vlan error: unknown command %s", p_argv[i_command].psz_str );
+ intf_IntfMsg("channel error: unknown command %s", p_argv[i_command].psz_str );
return( INTF_USAGE_ERROR );
}
* and spawn threads.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: main.c,v 1.82 2001/04/06 09:15:47 sam Exp $
+ * $Id: main.c,v 1.83 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
#include "beos_specific.h"
#endif
+#include "netutils.h" /* network_ChannelJoin */
+
#include "main.h"
/*****************************************************************************
#define OPT_FULLSCREEN 165
#define OPT_OVERLAY 166
-#define OPT_VLANS 170
+#define OPT_CHANNELS 170
#define OPT_SERVER 171
#define OPT_PORT 172
#define OPT_BROADCAST 173
/* Input options */
{ "input", 1, 0, OPT_INPUT },
- { "vlans", 0, 0, OPT_VLANS },
+ { "channels", 0, 0, OPT_CHANNELS },
{ "server", 1, 0, OPT_SERVER },
{ "port", 1, 0, OPT_PORT },
{ "broadcast", 0, 0, OPT_BROADCAST },
/*
* Initialize shared resources and libraries
*/
- /* FIXME: no VLANs */
-#if 0
- if( p_main->b_vlans && input_VlanCreate() )
+ if( p_main->b_channels && network_ChannelCreate() )
{
- /* On error during vlans initialization, switch off vlans */
- intf_Msg( "Virtual LANs initialization failed : "
- "vlans management is deactivated" );
- p_main->b_vlans = 0;
+ /* On error during Channels initialization, switch off channels */
+ intf_Msg( "Channels initialization failed : "
+ "Channel management is deactivated" );
+ p_main->b_channels = 0;
}
-#endif
/*
* Run interface
}
/*
- * Free shared resources and libraries
+ * Go back into channel 0 which is the network
*/
- /* FIXME */
-#if 0
- if( p_main->b_vlans )
+ if( p_main->b_channels )
{
- input_VlanDestroy();
+ network_ChannelJoin( COMMON_CHANNEL );
}
-#endif
/*
* Free module bank
p_main->ppsz_argv = ppsz_argv;
p_main->ppsz_env = ppsz_env;
- p_main->b_audio = 1;
- p_main->b_video = 1;
- p_main->b_vlans = 0;
+ p_main->b_audio = 1;
+ p_main->b_video = 1;
+ p_main->b_channels = 0;
p_main->i_warning_level = 4;
case OPT_INPUT: /* --input */
main_PutPszVariable( INPUT_METHOD_VAR, optarg );
break;
- case OPT_VLANS: /* --vlans */
- p_main->b_vlans = 1;
+ case OPT_CHANNELS: /* --channels */
+ p_main->b_channels = 1;
break;
case OPT_SERVER: /* --server */
main_PutPszVariable( INPUT_SERVER_VAR, optarg );
"\n -s, --dvdsubtitle <channel> \tchoose DVD subtitle channel"
"\n"
"\n --input \tinput method"
- "\n --vlans \tenable vlans"
+ "\n --channels \tenable channels"
"\n --server <host> \tvideo server address"
"\n --port <port> \tvideo server port"
"\n --broadcast \tlisten to a broadcast"
"\n " INPUT_PORT_VAR "=<port> \tvideo server port"
"\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface"
"\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode"
- "\n " INPUT_VLAN_SERVER_VAR "=<hostname> \tvlan server"
- "\n " INPUT_VLAN_PORT_VAR "=<port> \tvlan server port" );
+ "\n " INPUT_CHANNEL_SERVER_VAR "=<hostname> \tchannel server"
+ "\n " INPUT_CHANNEL_PORT_VAR "=<port> \tchannel server port" );
}
* netutils.c: various network functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: netutils.c,v 1.22 2001/03/21 13:42:34 sam Exp $
+ * $Id: netutils.c,v 1.23 2001/04/11 02:01:24 henri Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Benoit Steiner <benny@via.ecp.fr>
#include <errno.h> /* errno() */
#include <string.h> /* bzero(), bcopy() */
#include <unistd.h> /* gethostname() */
+#include <sys/time.h> /* gettimeofday */
#include <netinet/in.h> /* BSD: struct in_addr */
#include <sys/socket.h> /* BSD: struct sockaddr */
#include <arpa/inet.h> /* inet_ntoa(), inet_aton() */
#endif
+#ifdef SYS_LINUX
+#include <sys/ioctl.h> /* ioctl() */
+#endif
+
#if defined (HAVE_NET_IF_H)
#include <net/if.h> /* interface (arch-dependent) */
#endif
#include "common.h"
#include "mtime.h"
#include "threads.h"
+#include "main.h"
#include "intf_msg.h"
-#if !defined( SYS_BEOS ) && !defined( SYS_NTO )
-
#include "netutils.h"
+
+
/*****************************************************************************
- * input_BuildLocalAddr : fill a sockaddr_in structure for local binding
+ * input_channel_t: channel library data
+ *****************************************************************************
+ * Store global channel library data.
+ * The part of the code concerning the channel changing process is unstable
+ * as it depends on the VideoLAN channel server, which isn't frozen for
+ * the time being.
+ *****************************************************************************/
+typedef struct input_channel_s
+{
+ int i_channel_id; /* current channel number */
+ mtime_t last_change; /* last change date */
+} input_channel_t;
+
+
+/*****************************************************************************
+ * network_BuildLocalAddr : fill a sockaddr_in structure for local binding
*****************************************************************************/
int network_BuildLocalAddr( struct sockaddr_in * p_socket, int i_port,
boolean_t b_broadcast )
}
/*****************************************************************************
- * input_BuildRemoteAddr : fill a sockaddr_in structure for remote host
+ * network_BuildRemoteAddr : fill a sockaddr_in structure for remote host
*****************************************************************************/
int network_BuildRemoteAddr( struct sockaddr_in * p_socket, char * psz_server )
{
}
return( 0 );
}
-#endif
+/*****************************************************************************
+ * network_ChannelCreate: initialize global channel method data
+ *****************************************************************************
+ * Initialize channel input method global data. This function should be called
+ * once before any input thread is created or any call to other
+ * input_Channel*() function is attempted.
+ *****************************************************************************/
+int network_ChannelCreate( void )
+{
+/* Even when BSD are supported, BeOS is not likely to be supported, so
+ * I prefer to put it apart */
+#ifdef SYS_BEOS
+ intf_ErrMsg( "error: channel changing is not yet supported under BeOS" );
+ return( 1 );
+#else
+/* FIXME : channels handling only work for linux */
+#ifdef SYS_LINUX
+ /* Allocate structure */
+ p_main->p_channel = malloc( sizeof( input_channel_t ) );
+ if( p_main->p_channel == NULL )
+ {
+ intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+ return( -1 );
+ }
+
+ /* Initialize structure */
+ p_main->p_channel->i_channel_id = 0;
+ p_main->p_channel->last_change = 0;
+
+ intf_Msg("Channels initialized\n");
+ return( 0 );
+#else
+ intf_ErrMsg( "error : channel changing only works with linux yest" );
+#endif /* SYS_LINUX */
+#endif /* SYS_BEOS */
+}
+
+/*****************************************************************************
+ * network_ChannelJoin: join a channel
+ *****************************************************************************
+ * This function will try to join a channel. If the relevant interface is
+ * already on the good channel, nothing will be done. Else, and if possible
+ * (if the interface is not locked), the channel server will be contacted
+ * and a change will be requested. The function will block until the change
+ * is effective. Note that once a channel is no more used, it's interface
+ * should be unlocked using input_ChannelLeave().
+ * Non 0 will be returned in case of error.
+ *****************************************************************************/
+int network_ChannelJoin( int i_channel_id )
+{
+ intf_ErrMsg("Changing to channel %d",i_channel_id);
+ return(0);
+/* Courtesy of Nitrox. He'll update it soon */
+#if 0
+/* I still prefer to put BeOS a bit apart */
+#ifdef SYS_BEOS
+ intf_ErrMsg( "Channels are not yet supported uunder BeOS" );
+ return( -1 );
+#else
+#ifdef SYS_LINUX
+ int socket_cl;
+ int fromlen;
+ struct ifreq interface;
+ struct sockaddr_in sa_server;
+ struct sockaddr_in sa_client;
+ unsigned int version = 12;
+ char mess[80];
+ char mess_length = 80;
+ struct timeval *date_cl;
+ struct timeval time;
+ long unsigned int date;
+ int nbanswer;
+ char answer;
+ fd_set rfds;
+ unsigned int rc;
+/* debug */ intf_ErrMsg("ChannelJoin : %d",i_channel_id);
+ /* If last change is too recent, wait a while */
+ if( mdate() - p_main->p_channel->last_change < INPUT_CHANNEL_CHANGE_DELAY )
+ {
+ intf_Msg("Waiting before changing channel...\n");
+ mwait( p_main->p_channel->last_change + INPUT_CHANNEL_CHANGE_DELAY );
+ }
+ p_main->p_channel->last_change = mdate();
+ p_main->p_channel->i_channel_id = i_channel_id;
+
+ intf_Msg("Joining channel %d\n", i_channel_id );
+
+ /*
+ * Looking for information about the eth0 interface
+ */
+ interface.ifr_addr.sa_family=AF_INET;
+ strcpy(interface.ifr_name,INPUT_IFACE_DEFAULT);
+
+
+ /*
+ * Initialysing the socket
+ */
+ socket_cl=socket(AF_INET,SOCK_DGRAM,0);
+
+
+ /*
+ * Getting the server's information
+ */
+ bzero(&sa_server,sizeof(struct sockaddr_in));
+ sa_server.sin_family=AF_INET;
+ sa_server.sin_port=htons(INPUT_CHANNEL_PORT_DEFAULT);
+ inet_aton(INPUT_CHANNEL_SERVER_DEFAULT,&(sa_server.sin_addr));
+
+ /*
+ * Looking for the interface MAC address
+ */
+ ioctl(socket_cl,SIOCGIFHWADDR,&interface);
+ intf_DbgMsg(
+ "CHANNELSERVER: macaddr == %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ interface.ifr_hwaddr.sa_data[0] & 0xff,
+ interface.ifr_hwaddr.sa_data[1] & 0xff,
+ interface.ifr_hwaddr.sa_data[2] & 0xff,
+ interface.ifr_hwaddr.sa_data[3] & 0xff,
+ interface.ifr_hwaddr.sa_data[4] & 0xff,
+ interface.ifr_hwaddr.sa_data[5] & 0xff);
+
+ /*
+ * Getting date of the client
+ */
+ date_cl=malloc(sizeof(struct timeval));
+ if(date_cl==NULL)
+ {
+ intf_ErrMsg("CHANNELSERVER: unable to allocate memory\n");
+ /* return VS_R_MEMORY;*/
+ return -1;
+ }
+
+ if (gettimeofday(date_cl,0)==-1)
+ return -1;
+ date=date_cl->tv_sec;
+ free(date_cl);
+ intf_DbgMsg("CHANNELSERVER: date %lu\n",date);
+
+
+ /*
+ * Build of the message
+ */
+ sprintf(mess,"%d %u %lu %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",
+ i_channel_id, version, date,
+ interface.ifr_hwaddr.sa_data[0] & 0xff,
+ interface.ifr_hwaddr.sa_data[1] & 0xff,
+ interface.ifr_hwaddr.sa_data[2] & 0xff,
+ interface.ifr_hwaddr.sa_data[3] & 0xff,
+ interface.ifr_hwaddr.sa_data[4] & 0xff,
+ interface.ifr_hwaddr.sa_data[5] & 0xff);
+
+ intf_DbgMsg("CHANNELSERVER: The message is %s\n",mess);
+
+
+ /*
+ * Open the socket 2
+ */
+ bzero(&sa_client,sizeof(struct sockaddr_in));
+ sa_client.sin_family=AF_INET;
+ sa_client.sin_port=htons(4312);
+ sa_client.sin_addr.s_addr=INADDR_ANY;
+ fromlen=sizeof(struct sockaddr);
+ rc=bind(socket_cl,(struct sockaddr *)(&sa_client),sizeof(struct sockaddr));
+ if (rc)
+ {
+ intf_ErrMsg("CHANNELSERVER: Unable to bind socket:%u\n",rc);
+ /* TODO put CS_R_BIND in types.h*/
+ /* return CS_R_SOCKET;*/
+ return -1;
+ }
+
+
+ /*
+ * Send the message
+ */
+ sendto(socket_cl,mess,mess_length,0,(struct sockaddr *)(&sa_server),\
+ sizeof(struct sockaddr));
+
+ /*
+ * Waiting 5 sec for one answer from the server
+ */
+ time.tv_sec=5;
+ time.tv_usec=0;
+ FD_ZERO(&rfds);
+ FD_SET(socket_cl,&rfds);
+ nbanswer=select(socket_cl+1,&rfds,NULL,NULL,&time);
+ if(nbanswer==0)
+ intf_DbgMsg("CHANNELSERVER: no answer\n");
+ else if(nbanswer==-1)
+ intf_DbgMsg("CHANNELSERVER: Unable to receive the answer\n");
+ else
+ {
+ recvfrom(socket_cl,&answer,sizeof(char),0,\
+ (struct sockaddr *)(&sa_client),&fromlen);
+ intf_DbgMsg("CHANNELSERVER: the answer : %hhd\n",answer);
+ if(answer==-1)
+ intf_DbgMsg(
+ "CHANNELSERVER: The server failed to create the thread\n");
+ else if(answer==0)
+ intf_DbgMsg(
+ "CHANNELSERVER: The server tries to change the channel\n");
+ else
+ intf_DbgMsg("CHANNELSERVER: Unknown answer !\n");
+ }
+
+ /*
+ * Close the socket
+ */
+ close(socket_cl);
+
+ return 0;
+#else /* SYS_LINUX */
+ intf_ErrMsg( "Channel only work under linux yet" );
+#endif /* SYS_LINUX */
+
+}
+#endif /* SYS_BEOS */
+#endif /* if 0 */
+}