Commit 063cb8b6 authored by Clément Stenac's avatar Clément Stenac

Remove slp and joystick plugins

parent 74df93df
......@@ -7,7 +7,6 @@ SOURCES_access_ftp = ftp.c
SOURCES_access_smb = smb.c
SOURCES_dvdnav = dvdnav.c
SOURCES_dvdread = dvdread.c
SOURCES_slp = slp.c
SOURCES_access_fake = fake.c
SOURCES_cdda = \
cdda.c \
......
/*****************************************************************************
* slp.c: SLP access plugin
*****************************************************************************
* Copyright (C) 2002-2004 the VideoLAN team
* $Id$
*
* Authors: Loc Minier <lool@videolan.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
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc */
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc_playlist.h>
#include <slp.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static ssize_t Read( input_thread_t *, byte_t *, size_t );
static int Init ( vlc_object_t * );
static void End ( vlc_object_t * );
static int Demux ( input_thread_t * );
int i_group;
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#if 0
#define SRVTYPE_TEXT /*N_*/("SLP service type")
#define SRVTYPE_LONGTEXT /*N_*/( \
"The service type string for SLP queries, including the authority " \
"string (if any) for the request. May not be empty." )
#endif
#define ATTRIDS_TEXT N_("SLP attribute identifiers")
#define ATTRIDS_LONGTEXT N_( \
"This string is a comma separated list of attribute identifiers to " \
"search for a playlist title or empty to use all attributes." )
#define SCOPELIST_TEXT N_("SLP scopes list")
#define SCOPELIST_LONGTEXT N_( \
"This string is a comma separated list of scope names or empty if you " \
"want to use the default scopes. It is used in all SLP queries." )
#define NAMINGAUTHORITY_TEXT N_("SLP naming authority")
#define NAMINGAUTHORITY_LONGTEXT N_( \
"This string is a list of naming authorities to search. " \
"Use \"*\" for all and the empty string for the default of IANA." )
#define FILTER_TEXT N_("SLP LDAP filter")
#define FILTER_LONGTEXT N_( \
"This is a query formulated of attribute pattern matching expressions " \
"in the form of an LDAPv3 search filter or empty for all answers." )
#define LANG_TEXT N_("Language requested in SLP requests")
#define LANG_LONGTEXT N_( \
"RFC 1766 Language tag for the natural language locale of requests, " \
"leave empty to use the default locale. It is used in all SLP queries." )
vlc_module_begin();
set_description( _("SLP input") );
add_string( "slp-attrids", "", NULL, ATTRIDS_TEXT, ATTRIDS_LONGTEXT,
VLC_TRUE );
add_string( "slp-scopelist", "", NULL, SCOPELIST_TEXT,
SCOPELIST_LONGTEXT, VLC_TRUE );
add_string( "slp-namingauthority", "*", NULL, NAMINGAUTHORITY_TEXT,
NAMINGAUTHORITY_LONGTEXT, VLC_TRUE );
add_string( "slp-filter", "", NULL, FILTER_TEXT, FILTER_LONGTEXT,
VLC_TRUE );
add_string( "slp-lang", "", NULL, LANG_TEXT, LANG_LONGTEXT, VLC_TRUE );
set_capability( "access", 0 );
set_callbacks( Open, Close );
add_submodule();
add_shortcut( "demux_slp" );
set_capability( "demux", 0 );
set_callbacks( Init, End );
vlc_module_end();
/*****************************************************************************
* AttrCallback: updates the description of a playlist item
*****************************************************************************/
static SLPBoolean AttrCallback( SLPHandle slph_slp,
const char * psz_attrlist,
SLPError slpe_errcode,
void * p_cookie )
{
playlist_item_t * p_playlist_item = (playlist_item_t *)p_cookie;
/* our callback was only called to tell us there's nothing more to read */
if( slpe_errcode == SLP_LAST_CALL )
{
return SLP_TRUE;
}
/* or there was a problem with getting the data we requested */
if( (slpe_errcode != SLP_OK) )
{
#if 0
msg_Err( (vlc_object_t*)NULL,
"AttrCallback got an error %i with attribute %s",
slpe_errcode,
psz_attrlist );
#endif
return SLP_TRUE;
}
if( p_playlist_item->input.psz_name )
free( p_playlist_item->input.psz_name );
p_playlist_item->input.psz_name = strdup(psz_attrlist); /* NULL is checked */
return SLP_TRUE;
}
/*****************************************************************************
* SrvUrlCallback: adds an entry to the playlist
*****************************************************************************/
static SLPBoolean SrvUrlCallback( SLPHandle slph_slp,
const char * psz_srvurl,
uint16_t i_lifetime,
SLPError slpe_errcode,
void * p_cookie )
{
input_thread_t *p_input = (input_thread_t *)p_cookie;
playlist_t * p_playlist;
char psz_item[42] = ""; //"udp:@";
char * psz_s; /* to hold the uri of the stream */
SLPHandle slph_slp3;
SLPError slpe_result;
playlist_item_t * p_playlist_item;
/* our callback was only called to tell us there's nothing more to read */
if( slpe_errcode == SLP_LAST_CALL )
{
return SLP_TRUE;
}
msg_Dbg( p_input,"URL: %s", psz_srvurl );
/* or there was a problem with getting the data we requested */
if( (slpe_errcode != SLP_OK) )
{
msg_Err( p_input, "SrvUrlCallback got an error %i with URL %s",
slpe_errcode, psz_srvurl );
return SLP_TRUE;
}
/* search the returned address after a double-slash */
psz_s = strstr( psz_srvurl, "//" );
if( psz_s == NULL )
{
msg_Err( p_input,
"SrvUrlCallback got a strange string of your libslp" );
return SLP_TRUE;
}
/* skip the slashes */
psz_s = &psz_s[2];
/* add udp:@ in front of the address */
psz_s = strncat( psz_item,
psz_s,
sizeof(psz_item) - strlen(psz_item) - 1 );
/* create a playlist item */
p_playlist_item = playlist_ItemNew( p_input, psz_s, NULL );
if( p_playlist_item == NULL )
{
msg_Err( p_input, "out of memory" );
return SLP_TRUE;
}
p_playlist_item->i_group = i_group;
p_playlist_item->b_enabled = VLC_TRUE;
/* search the description of the stream */
if( SLPOpen( config_GetPsz( p_input, "slp-lang" ),
SLP_FALSE, /* synchronous ops */
&slph_slp3 ) == SLP_OK )
{
/* search all attributes */
slpe_result = SLPFindAttrs( slph_slp3,
psz_srvurl,
config_GetPsz( p_input, "slp-scopelist" ),
config_GetPsz( p_input, "slp-attrids" ),
AttrCallback,
p_playlist_item
);
/* we're done, clean up */
SLPClose( slph_slp3 );
}
/* search the main playlist object */
p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
msg_Warn( p_input, "could not find playlist, not adding entries" );
return SLP_TRUE;
}
playlist_AddItem( p_playlist, p_playlist_item,
PLAYLIST_APPEND, PLAYLIST_END );
vlc_object_release( p_playlist );
msg_Info( p_input, "added %s (lifetime %i) to playlist",
psz_srvurl, i_lifetime );
return SLP_TRUE;
}
/*****************************************************************************
* SrvTypeCallback: searchs all servers of a certain type
*****************************************************************************/
static SLPBoolean SrvTypeCallback( SLPHandle slph_slp,
const char * psz_srvurl,
SLPError slpe_errcode,
void * p_cookie )
{
input_thread_t * p_input = (input_thread_t *)p_cookie;
SLPError slpe_result;
SLPHandle slph_slp2;
char *psz_eos;
char *psz_service;
msg_Dbg( p_input, "services: %s", psz_srvurl );
/* our callback was only called to tell us there's nothing more to read */
if( slpe_errcode == SLP_LAST_CALL )
{
return SLP_TRUE;
}
msg_Dbg( p_input, "services: %s", psz_srvurl );
/* or there was a problem with getting the data we requested */
if( slpe_errcode != SLP_OK )
{
msg_Err( p_input, "SrvTypeCallback got an error %i with URL %s",
slpe_errcode, psz_srvurl );
return SLP_TRUE;
}
/* get a new handle to the library */
if( SLPOpen( config_GetPsz( p_input, "slp-lang" ),
SLP_FALSE, /* synchronous ops */
&slph_slp2 ) == SLP_OK )
{
/* search for services */
while(1)
{
if( *psz_srvurl == '\0') break;
if( !strncasecmp( psz_srvurl, "service:", 8 ) )
{
while(1)
{
psz_eos = strchr( psz_srvurl, ',');
if(!psz_eos) break;
if(!strncasecmp(psz_eos+1,"service:",8)) break;
}
if(psz_eos)
*psz_eos = '\0';
psz_service = strdup( psz_srvurl);
msg_Dbg( p_input, "getting details for %s", psz_service );
slpe_result = SLPFindSrvs( slph_slp2,
psz_service,
config_GetPsz( p_input, "slp-scopelist" ),
config_GetPsz( p_input, "slp-filter" ),
SrvUrlCallback,
p_input );
if(psz_eos)
psz_srvurl = psz_eos;
#if 0
SLPClose( slph_slp2 );
#endif
if( slpe_result != SLP_OK )
{
msg_Err( p_input,
"SLPFindSrvs error %i finding servers of type %s",
slpe_result, psz_service );
}
}
psz_srvurl++;
}
}
SLPClose( slph_slp2 );
return SLP_TRUE;
}
/*****************************************************************************
* Open: initialize library for the access module
*****************************************************************************/
static int Open( vlc_object_t * p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
SLPError slpe_result;
SLPHandle slph_slp;
playlist_t * p_playlist;
playlist_group_t * p_group;
/* remove the "slp:" entry of the playlist */
p_playlist = (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( !p_playlist )
{
msg_Warn( p_input, "hey I can't find the main playlist, I need it" );
return VLC_FALSE;
}
p_group = playlist_CreateGroup( p_playlist , "SLP" );
i_group = p_group->i_id;
p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
vlc_object_release( (vlc_object_t *)p_playlist );
/* get a new handle to the library */
if( SLPOpen( config_GetPsz( p_input, "slp-lang" ),
SLP_FALSE, /* synchronous ops */
&slph_slp ) == SLP_OK )
{
/* search all service types */
slpe_result =
SLPFindSrvTypes( slph_slp,
config_GetPsz( p_input, "slp-namingauthority" ),
config_GetPsz( p_input, "slp-scopelist" ),
SrvTypeCallback,
p_input );
/* we're done, clean up */
SLPClose( slph_slp );
}
if( !p_input->psz_demux || !*p_input->psz_demux )
{
p_input->psz_demux = "demux_slp";
}
p_input->pf_read = Read;
p_input->pf_set_program = NULL;
p_input->pf_set_area = NULL;
p_input->pf_seek = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = VLC_FALSE;
p_input->stream.b_seekable = VLC_FALSE;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.p_selected_area->i_size = 0;
p_input->stream.i_method = INPUT_METHOD_SLP;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_input->i_mtu = 0;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: close access
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
return;
}
/*****************************************************************************
* Read: should fill but zeroes the buffer
*****************************************************************************/
static ssize_t Read ( input_thread_t *p_input, byte_t *p_buffer, size_t s )
{
memset( p_buffer, 0, s );
return s;
}
/*****************************************************************************
* Init: initialize demux
*****************************************************************************/
static int Init ( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t *)p_this;
if( p_input->stream.i_method != INPUT_METHOD_SLP )
{
return VLC_FALSE;
}
p_input->pf_demux = Demux;
p_input->pf_demux_control = demux_vaControlDefault;
p_input->pf_rewind = NULL;
return VLC_SUCCESS;
}
/*****************************************************************************
* Demux: should demux but does nothing
*****************************************************************************/
static int Demux ( input_thread_t * p_input )
{
return 0;
}
/*****************************************************************************
* End: end demux
*****************************************************************************/
static void End ( vlc_object_t *p_this )
{
return;
}
......@@ -4,7 +4,6 @@ SOURCES_http = http.c
SOURCES_telnet = telnet.c
SOURCES_netsync = netsync.c
SOURCES_ntservice = ntservice.c
SOURCES_joystick = joystick.c
SOURCES_hotkeys = hotkeys.c
SOURCES_lirc = lirc.c
SOURCES_rc = rc.c
/*****************************************************************************
* joystick.c: control vlc with a joystick
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <errno.h>
#include <fcntl.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <linux/joystick.h>
#include "audio_output.h"
/* Default values for parameters */
#define DEFAULT_MAX_SEEK 10 /* seconds */
#define DEFAULT_REPEAT 100
#define DEFAULT_WAIT 500
#define DEFAULT_DEVICE "/dev/input/js0"
#define DEFAULT_THRESHOLD 12000 /* 0 -> 32767 */
#define DEFAULT_MAPPING \
"{axis-0-up=forward,axis-0-down=back," \
"axis-1-up=next,axis-1-down=prev," \
"butt-1-down=play,butt-2-down=fullscreen}"
/* Default Actions (used if there are missing actions in the default
* Available actions are: Next,Prev, Forward,Back,Play,Fullscreen,dummy */
#define AXIS_0_UP_ACTION Forward
#define AXIS_0_DOWN_ACTION Back
#define AXIS_1_UP_ACTION Next
#define AXIS_1_DOWN_ACTION Prev
#define BUTTON_1_PRESS_ACTION Play
#define BUTTON_1_RELEASE_ACTION dummy
#define BUTTON_2_PRESS_ACTION Fullscreen
#define BUTTON_2_RELEASE_ACTION dummy
/*****************************************************************************
* intf_sys_t: description and status of interface
*****************************************************************************/
typedef int (*action)(intf_thread_t *p_intf);
struct joy_axis_t
{
int b_trigered; /* Are we in the trigger zone ? */
int i_value; /* Value of movement */
int b_dowork; /* Do we have to do the action ? */
action pf_actup; /* Action when axis is up */
action pf_actdown; /* Action when axis is down */
mtime_t l_time; /* When did the axis enter the trigger
* zone ? */
};
struct joy_button_t
{
action pf_actup; /* What to do when button is released */
action pf_actdown;/* What to do when button is pressed */
};
struct intf_sys_t
{
int i_fd; /* File descriptor for joystick */
struct timeval timeout; /* Select timeout */
int i_threshold; /* motion threshold */
int i_wait; /* How much to wait before repeat */
int i_repeat; /* Repeat time */
int i_maxseek; /* Maximum seek time */
struct joy_axis_t axes[3]; /* Axes descriptor */
struct joy_button_t buttons[2]; /* Buttons descriptor */
input_thread_t *p_input; /* Input thread (for seeking) */
float f_seconds; /* How much to seek */
};
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int Init ( intf_thread_t *p_intf );
static int handle_event ( intf_thread_t *p_intf, struct js_event event );
/* Actions */
static int Next (intf_thread_t *p_intf);
static int Prev (intf_thread_t *p_intf);
static int Back (intf_thread_t *p_intf);
static int Forward (intf_thread_t *p_intf);
static int Play (intf_thread_t *p_intf);
static int Fullscreen (intf_thread_t *p_intf);
static int dummy (intf_thread_t *p_intf);
/* Exported functions */
static void Run ( intf_thread_t *p_intf );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define THRESHOLD_TEXT N_( "Motion threshold" )
#define THRESHOLD_LONGTEXT N_( \
"Amount of joystick movement required for a movement to be " \
"recorded (0->32767)." )
#define DEVICE_TEXT N_( "Joystick device" )
#define DEVICE_LONGTEXT N_( \
"The joystick device (usually /dev/js0 or /dev/input/js0).")
#define REPEAT_TEXT N_( "Repeat time (ms)" )
#define REPEAT_LONGTEXT N_( \
"Delay waited before the action is repeated if it is still " \
"triggered, in milliseconds." )
#define WAIT_TEXT N_( "Wait time (ms)")
#define WAIT_LONGTEXT N_(\
"The time waited before the repeat starts, in milliseconds.")
#define SEEK_TEXT N_( "Max seek interval (seconds)")
#define SEEK_LONGTEXT N_(\
"The maximum number of seconds that will be sought at a time." )
#define MAP_TEXT N_( "Action mapping")
#define MAP_LONGTEXT N_( "Allows you to remap the actions." )
vlc_module_begin();
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_CONTROL );
add_integer( "motion-threshold", DEFAULT_THRESHOLD, NULL,
THRESHOLD_TEXT, THRESHOLD_LONGTEXT, VLC_TRUE );
add_string( "joystick-device", DEFAULT_DEVICE, NULL,
DEVICE_TEXT, DEVICE_LONGTEXT, VLC_TRUE );
add_integer ("joystick-repeat", DEFAULT_REPEAT,NULL,
REPEAT_TEXT, REPEAT_LONGTEXT, VLC_TRUE );
add_integer ("joystick-wait", DEFAULT_WAIT,NULL,
WAIT_TEXT, WAIT_LONGTEXT, VLC_TRUE );
add_integer ("joystick-max-seek",DEFAULT_MAX_SEEK,NULL,
SEEK_TEXT, SEEK_LONGTEXT, VLC_TRUE );
add_string("joystick-mapping",DEFAULT_MAPPING,NULL,
MAP_TEXT,MAP_LONGTEXT, VLC_TRUE );
set_description( _("Joystick control interface") );
set_capability( "interface", 0 );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Open: initialize interface
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
return VLC_ENOMEM;
}
if( Init( p_intf ) < 0 )
{
msg_Err( p_intf, "cannot initialize interface" );
free( p_intf->p_sys );
return VLC_EGENERIC;
}
msg_Dbg( p_intf, "interface initialized" );
p_intf->pf_run = Run;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy the interface
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Destroy structure */
if( p_intf->p_sys )
{
free( p_intf->p_sys );
}
}
/*****************************************************************************
* Run: main loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
int i_sel_res = 0;
int i_read = 0;
int i_axis = 0;
struct js_event event;
/* Main loop */
while( !p_intf->b_die )
{
fd_set fds;
vlc_mutex_lock( &p_intf->change_lock );
FD_ZERO( &fds );
FD_SET( p_intf->p_sys->i_fd, &fds );
p_intf->p_sys->timeout.tv_sec = 0;
p_intf->p_sys->timeout.tv_usec = p_intf->p_sys->i_repeat;
i_sel_res = select( p_intf->p_sys->i_fd + 1, &fds,
NULL, NULL, &p_intf->p_sys->timeout );
p_intf->p_sys->p_input = (input_thread_t *)
vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
if( i_sel_res == -1 && errno != EINTR )
{
msg_Err( p_intf, "select error: %s",strerror(errno) );
}
else if(i_sel_res > 0 && FD_ISSET( p_intf->p_sys->i_fd, &fds))
{
/* We got an event */
memset(&event,0,sizeof(struct js_event));
i_read = read( p_intf->p_sys->i_fd, &event,
sizeof(struct js_event));
handle_event( p_intf, event ) ;
}
else if(i_sel_res == 0)
{
/*We have no event, but check if we have an action to repeat */
for(i_axis = 0; i_axis <= 1; i_axis++)
{
if( p_intf->p_sys->axes[i_axis].b_trigered &&
mdate()-p_intf->p_sys->axes[i_axis].l_time >
p_intf->p_sys->i_wait &&
p_intf->p_sys->axes[i_axis].i_value > 0 )
{
p_intf->p_sys->axes[i_axis].pf_actup(p_intf);
}
if( p_intf->p_sys->axes[i_axis].b_trigered &&
mdate()-p_intf->p_sys->axes[i_axis].l_time >
p_intf->p_sys->i_wait &&
p_intf->p_sys->axes[i_axis].i_value < 0 )
{
p_intf->p_sys->axes[i_axis].pf_actdown(p_intf);
}
}
}
if(p_intf->p_sys->p_input)
vlc_object_release (p_intf->p_sys->p_input);
vlc_mutex_unlock ( &p_intf->change_lock );
}
}
/*****************************************************************************
* InitThread: Initialize the interface
*****************************************************************************/
static int Init( intf_thread_t * p_intf )
{
char *psz_device;
char *psz_parse;
char *psz_eof; /* end of field */
psz_device = config_GetPsz( p_intf, "joystick-device");
if( !psz_device ) /* strange... */
{
psz_device = strdup( DEFAULT_DEVICE );
}
p_intf->p_sys->i_fd = open( psz_device, O_RDONLY|O_NONBLOCK );
if( p_intf->p_sys->i_fd == -1 )
{
msg_Warn( p_intf, "unable to open %s for reading: %s",
psz_device, strerror(errno) );
return VLC_EGENERIC;
}
p_intf->p_sys->i_repeat = 1000 * config_GetInt( p_intf, "joystick-repeat");
p_intf->p_sys->i_wait = 1000 * config_GetInt( p_intf, "joystick-wait");
p_intf->p_sys->i_threshold = config_GetInt( p_intf, "motion-threshold" );
if(p_intf->p_sys->i_threshold > 32767 || p_intf->p_sys->i_threshold < 0 )
p_intf->p_sys->i_threshold = DEFAULT_THRESHOLD;
p_intf->p_sys->i_maxseek = config_GetInt( p_intf, "joystick-max-seek" );
psz_parse = config_GetPsz( p_intf, "joystick-mapping" ) ;
if( ! psz_parse)
{
msg_Warn (p_intf,"invalid mapping. aborting" );
return VLC_EGENERIC;
}
if( !strlen( psz_parse ) )
{
msg_Warn( p_intf, "invalid mapping, aborting" );
return VLC_EGENERIC;
}
p_intf->p_sys->axes[0].pf_actup = AXIS_0_UP_ACTION;
p_intf->p_sys->axes[0].pf_actdown = AXIS_0_DOWN_ACTION;
p_intf->p_sys->axes[1].pf_actup = AXIS_1_UP_ACTION;
p_intf->p_sys->axes[1].pf_actdown = AXIS_1_DOWN_ACTION;
p_intf->p_sys->buttons[0].pf_actdown = BUTTON_1_PRESS_ACTION;
p_intf->p_sys->buttons[0].pf_actup = BUTTON_1_RELEASE_ACTION;
p_intf->p_sys->buttons[1].pf_actdown = BUTTON_2_PRESS_ACTION;
p_intf->p_sys->buttons[1].pf_actup = BUTTON_2_RELEASE_ACTION;
/* Macro to parse the command line */
#define PARSE(name,function) \
if(!strncmp( psz_parse, name, strlen( name ) ) ) \
{ \
psz_parse += strlen( name ); \
psz_eof = strchr( psz_parse, ',' ); \
if( !psz_eof) \
psz_eof = strchr( psz_parse, '}' ); \
if( !psz_eof) \
psz_eof = psz_parse + strlen(psz_parse); \
if( psz_eof ) \
{ \
*psz_eof = '\0' ; \
} \
msg_Dbg(p_intf,"%s -> %s", name,psz_parse) ; \
if(!strcasecmp( psz_parse, "play" ) ) function = Play; \
if(!strcasecmp( psz_parse, "next" ) ) function = Next; \
if(!strcasecmp( psz_parse, "prev" ) ) function = Prev; \
if(!strcasecmp( psz_parse, "fullscreen" ) ) function = Fullscreen; \
if(!strcasecmp( psz_parse, "forward" ) ) function = Forward; \
if(!strcasecmp( psz_parse, "back" ) ) function = Back; \
psz_parse = psz_eof; \
psz_parse ++; \
continue; \
} \
for( ; *psz_parse ; psz_parse++ )
{
PARSE("axis-0-up=", p_intf->p_sys->axes[0].pf_actup );
PARSE("axis-0-down=", p_intf->p_sys->axes[0].pf_actdown );
PARSE("axis-1-up=", p_intf->p_sys->axes[1].pf_actup );
PARSE("axis-1-down=", p_intf->p_sys->axes[1].pf_actdown );
PARSE("butt-1-up=", p_intf->p_sys->buttons[0].pf_actup );
PARSE("butt-1-down=", p_intf->p_sys->buttons[0].pf_actdown );
PARSE("butt-2-up=", p_intf->p_sys->buttons[1].pf_actup );
PARSE("butt-2-down=", p_intf->p_sys->buttons[1].pf_actdown );
}
p_intf->p_sys->axes[0].b_trigered = VLC_FALSE;
p_intf->p_sys->axes[0].l_time = 0;
p_intf->p_sys->axes[1].b_trigered = VLC_FALSE;
p_intf->p_sys->axes[1].l_time = 0;
return VLC_SUCCESS;
}
/*****************************************************************************
* handle_event : parse a joystick event and takes the appropriate action *
*****************************************************************************/
static int handle_event ( intf_thread_t *p_intf, struct js_event event)
{
unsigned int i_axis;
if( event.type == JS_EVENT_AXIS )
{
/* Third axis is supposed to behave in a different way: it is a
* throttle, and will set a value, without triggering anything */
if( event.number == 2 &&
/* Try to avoid Parkinson joysticks */
abs(event.value - p_intf->p_sys->axes[2].i_value) > 200 )
{
p_intf->p_sys->axes[2].i_value = event.value;
msg_Dbg( p_intf, "updating volume" );
/* This way, the volume is between 0 and 1024 */
aout_VolumeSet( p_intf, (32767-event.value)/64 );
return 0;
}
p_intf->p_sys->axes[event.number].b_dowork = VLC_FALSE;
p_intf->p_sys->axes[event.number].i_value = event.value;
if( abs(event.value) > p_intf->p_sys->i_threshold &&
p_intf->p_sys->axes[event.number].b_trigered == VLC_FALSE )
{
/* The axis entered the trigger zone. Start the event */
p_intf->p_sys->axes[event.number].b_trigered = VLC_TRUE;
p_intf->p_sys->axes[event.number].b_dowork = VLC_TRUE;
p_intf->p_sys->axes[event.number].l_time = mdate();
}
else if( abs(event.value) > p_intf->p_sys->i_threshold &&
p_intf->p_sys->axes[event.number].b_trigered == VLC_TRUE )
{
/* The axis moved but remained in the trigger zone
* Do nothing at this time */
}
else if( abs(event.value) < p_intf->p_sys->i_threshold )
{
/* The axis is not in the trigger zone */
p_intf->p_sys->axes[event.number].b_trigered = VLC_FALSE;
}
/* Special for seeking */
p_intf->p_sys->f_seconds = 1 +
(abs(event.value) - p_intf->p_sys->i_threshold) *
(p_intf->p_sys->i_maxseek - 1 ) /
(32767 - p_intf->p_sys->i_threshold);
/* Handle the first two axes. */
for(i_axis = 0; i_axis <= 1; i_axis ++)
{
if(p_intf->p_sys->axes[i_axis].b_dowork == VLC_TRUE)
{
if( p_intf->p_sys->axes[i_axis].i_value
> p_intf->p_sys->i_threshold )
{
msg_Dbg(p_intf,"up for axis %i\n",i_axis);
p_intf->p_sys->axes[i_axis].pf_actup(p_intf);
}
else if( p_intf->p_sys->axes[i_axis].i_value
< -p_intf->p_sys->i_threshold )
{
msg_Dbg(p_intf,"down for axis %i\n",i_axis);
p_intf->p_sys->axes[i_axis].pf_actdown(p_intf);
}
}
}
}
else if( event.type == JS_EVENT_BUTTON )
{
msg_Dbg( p_intf, "button %i %s", event.number,
event.value ? "pressed" : "released" );
if( event.number > 1 )
return 0; /* Only trigger 2 buttons */
if( event.value == 1 ) /* Button pressed */
{
if( p_intf->p_sys->buttons[event.number].pf_actdown )
p_intf->p_sys->buttons[event.number].pf_actdown( p_intf );
}
else /* Button released */
{
if( p_intf->p_sys->buttons[event.number].pf_actup )
p_intf->p_sys->buttons[event.number].pf_actup( p_intf );
}
}
return 0;
}
/****************************************************************************
* The actions
****************************************************************************/
/* Go to next item in the playlist */
static int Next( intf_thread_t *p_intf )
{
playlist_t *p_playlist;
p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return VLC_ENOOBJ;
}
playlist_Next( p_playlist );
vlc_object_release( p_playlist );
return VLC_SUCCESS;
}
/* Go to previous item in the playlist */
static int Prev( intf_thread_t *p_intf )
{
playlist_t *p_playlist;
p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return VLC_ENOOBJ;
}
playlist_Prev( p_playlist );
vlc_object_release( p_playlist );
return VLC_SUCCESS;
}
/* Seek forward */
static int Forward( intf_thread_t *p_intf )
{
if( p_intf->p_sys->p_input )
{
msg_Dbg( p_intf,"seeking %f seconds",p_intf->p_sys->f_seconds );
var_SetTime( p_intf->p_sys->p_input, "time-offset",
(int64_t)p_intf->p_sys->f_seconds * I64C(1000000) );
return VLC_SUCCESS;
}
return VLC_ENOOBJ;
}
/* Seek backwards */
static int Back( intf_thread_t *p_intf )
{
if( p_intf->p_sys->p_input )
{
msg_Dbg( p_intf,"seeking -%f seconds", p_intf->p_sys->f_seconds );
var_SetTime( p_intf->p_sys->p_input, "time-offset",
-(int64_t)p_intf->p_sys->f_seconds * I64C(1000000) );
return VLC_SUCCESS;
}
return VLC_ENOOBJ;
}
/* Toggle Play/Pause */
static int Play( intf_thread_t *p_intf )
{
if( p_intf->p_sys->p_input )
{
var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
return VLC_SUCCESS;
}
return VLC_ENOOBJ;
}
/* Toggle fullscreen mode */
static int Fullscreen( intf_thread_t *p_intf )
{
vout_thread_t * p_vout;
p_vout = vlc_object_find(p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_vout )
{
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
vlc_object_release(p_vout);
}
return VLC_SUCCESS;
}
/* dummy event. Use it if you don't wan't anything to happen */
static int dummy( intf_thread_t *p_intf )
{
return VLC_SUCCESS;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment