Commit d69ab00d authored by Henri Fallon's avatar Henri Fallon

- Ported the 0.2.0's channel changing functions
- Cosmetic changes : the word 'vlan' is disappearing
- network_ChannelJoin is still commented out as it's not in sync anymore
  with our channel server. Nitrox should fix this within a week.
- X and Xv output : added autohide cursor as in SDL
- X and Sv : keys 1 to 0 change channel
- SDL : keys F1 to F10 change channel as I was not able to make 1..0 work
parent b3d7d241
......@@ -3,7 +3,7 @@
* 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>
......@@ -103,11 +103,11 @@ typedef struct intf_channel_s * p_intf_channel_t;
/* 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 */
......
......@@ -190,7 +190,7 @@
#define INPUT_BROADCAST_DEFAULT 0
/*
* Vlan method
* Channel method
*/
/* Default network interface and environment variable */
......@@ -198,14 +198,14 @@
#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 */
......
......@@ -3,7 +3,7 @@
* 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>
*
......@@ -47,7 +47,7 @@ typedef struct
/* 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 */
......@@ -60,7 +60,7 @@ typedef struct
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;
......
......@@ -4,7 +4,7 @@
* 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>
......@@ -24,9 +24,13 @@
* 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 );
......@@ -2,7 +2,7 @@
* 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>
......@@ -52,6 +52,7 @@
/* FIXME: get rid of this */
#include "keystrokes.h"
#include "main.h"
#include "netutils.h"
/*****************************************************************************
* FIXME: this file is ... *
......@@ -274,7 +275,7 @@ static void vout_Destroy( vout_thread_t *p_vout )
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) )
......@@ -326,9 +327,8 @@ static int vout_Manage( vout_thread_t *p_vout )
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;
......@@ -357,11 +357,51 @@ static int vout_Manage( vout_thread_t *p_vout )
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;
......
......@@ -2,7 +2,7 @@
* 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>
......@@ -60,6 +60,8 @@
#include "interface.h"
#include "intf_msg.h"
#include "netutils.h" /* network_ChannelJoin */
#include "main.h"
/*****************************************************************************
......@@ -100,6 +102,9 @@ typedef struct vout_sys_s
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 ? */
......@@ -288,6 +293,10 @@ static int vout_Init( vout_thread_t *p_vout )
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 );
}
......@@ -352,6 +361,8 @@ static int vout_Manage( vout_thread_t *p_vout )
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
......@@ -360,7 +371,8 @@ static int vout_Manage( vout_thread_t *p_vout )
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 */
......@@ -394,16 +406,73 @@ static int vout_Manage( vout_thread_t *p_vout )
/* 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 */
......@@ -415,10 +484,6 @@ static int vout_Manage( vout_thread_t *p_vout )
/* in this part we will eventually manage
* clicks for DVD navigation for instance */
break;
case Button2:
X11TogglePointer( p_vout );
break;
}
}
/* Mouse release */
......@@ -432,6 +497,15 @@ static int vout_Manage( vout_thread_t *p_vout )
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
......@@ -519,6 +593,17 @@ static int vout_Manage( vout_thread_t *p_vout )
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;
}
......@@ -693,7 +778,8 @@ static int X11CreateWindow( vout_thread_t *p_vout )
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 )
{
......
......@@ -2,7 +2,7 @@
* 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>
......@@ -63,6 +63,8 @@
#include "interface.h"
#include "intf_msg.h"
#include "netutils.h" /* network_ChannelJoin */
#include "main.h"
/*****************************************************************************
......@@ -105,7 +107,10 @@ typedef struct vout_sys_s
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 ? */
......@@ -331,6 +336,7 @@ static int vout_Manage( vout_thread_t *p_vout )
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
......@@ -339,7 +345,8 @@ static int vout_Manage( vout_thread_t *p_vout )
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 */
......@@ -375,16 +382,73 @@ static int vout_Manage( vout_thread_t *p_vout )
/* 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 */
......@@ -396,10 +460,6 @@ static int vout_Manage( vout_thread_t *p_vout )
/* in this part we will eventually manage
* clicks for DVD navigation for instance */
break;
case Button2:
XVideoTogglePointer( p_vout );
break;
}
}
/* Mouse release */
......@@ -413,6 +473,16 @@ static int vout_Manage( vout_thread_t *p_vout )
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
......@@ -482,6 +552,16 @@ static int vout_Manage( vout_thread_t *p_vout )
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;
}
......@@ -684,7 +764,8 @@ static int XVideoCreateWindow( vout_thread_t *p_vout )
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 */
......
......@@ -4,7 +4,7 @@
* 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>
*
......@@ -322,16 +322,18 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
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) )
......@@ -380,4 +382,3 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
return( 0 );
}
......@@ -19,7 +19,7 @@
* 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>
*
......@@ -80,7 +80,7 @@ static int SpawnInput ( int i_argc, intf_arg_t *p_argv );
#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 );
/*
......@@ -170,11 +170,12 @@ const intf_command_t control_command[] =
/* 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
......@@ -186,16 +187,17 @@ const intf_command_t control_command[] =
"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",
......@@ -529,18 +531,18 @@ static int Test( int i_argc, intf_arg_t *p_argv )
#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 );
}
......@@ -564,7 +566,7 @@ static int Vlan( int i_argc, intf_arg_t *p_argv )
/* 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 );
}
......
......@@ -4,7 +4,7 @@
* 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>
......@@ -76,6 +76,8 @@
#include "beos_specific.h"
#endif
#include "netutils.h"