📄 joystick.c
字号:
*****************************************************************************/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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -