📄 joystick.c
字号:
/***************************************************************************** * joystick.c: control vlc with a joystick ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: joystick.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cl閙ent 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -