1 /*****************************************************************************
2 * lirc.c : lirc module for vlc
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
5 * $Id: lirc.c,v 1.11 2004/02/15 19:40:41 sigmunau Exp $
7 * Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
38 #include <lirc/lirc_client.h>
40 /*****************************************************************************
41 * intf_sys_t: description and status of FB interface
42 *****************************************************************************/
45 struct lirc_config *config;
46 vlc_mutex_t change_lock;
48 input_thread_t * p_input;
49 vout_thread_t * p_vout;
52 /*****************************************************************************
54 *****************************************************************************/
55 static int Open ( vlc_object_t * );
56 static void Close ( vlc_object_t * );
57 static void Run ( intf_thread_t * );
59 /*****************************************************************************
61 *****************************************************************************/
63 set_description( _("Infrared remote control interface") );
64 set_capability( "interface", 0 );
65 set_callbacks( Open, Close );
68 /*****************************************************************************
69 * Open: initialize interface
70 *****************************************************************************/
71 static int Open( vlc_object_t *p_this )
73 intf_thread_t *p_intf = (intf_thread_t *)p_this;
76 /* Allocate instance and initialize some members */
77 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
78 if( p_intf->p_sys == NULL )
80 msg_Err( p_intf, "out of memory" );
86 i_fd = lirc_init( "vlc", 1 );
89 msg_Err( p_intf, "lirc_init failed" );
90 free( p_intf->p_sys );
95 fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
97 if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
99 msg_Err( p_intf, "lirc_readconfig failed" );
101 free( p_intf->p_sys );
105 p_intf->p_sys->p_input = NULL;
110 /*****************************************************************************
111 * Close: destroy interface
112 *****************************************************************************/
113 static void Close( vlc_object_t *p_this )
115 intf_thread_t *p_intf = (intf_thread_t *)p_this;
117 if( p_intf->p_sys->p_input )
119 vlc_object_release( p_intf->p_sys->p_input );
121 if( p_intf->p_sys->p_vout )
123 vlc_object_release( p_intf->p_sys->p_vout );
125 /* Destroy structure */
126 lirc_freeconfig( p_intf->p_sys->config );
128 free( p_intf->p_sys );
131 /*****************************************************************************
133 *****************************************************************************/
134 static void Run( intf_thread_t *p_intf )
137 playlist_t *p_playlist;
138 input_thread_t *p_input;
139 vout_thread_t *p_vout = NULL;
141 while( !p_intf->b_die )
144 msleep( INTF_IDLE_SLEEP );
146 /* Update the input */
147 if( p_intf->p_sys->p_input == NULL )
149 p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
152 else if( p_intf->p_sys->p_input->b_dead )
154 vlc_object_release( p_intf->p_sys->p_input );
155 p_intf->p_sys->p_input = NULL;
157 p_input = p_intf->p_sys->p_input;
159 /* Update the vout */
162 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
164 p_intf->p_sys->p_vout = p_vout;
166 else if( p_vout->b_die )
168 vlc_object_release( p_vout );
170 p_intf->p_sys->p_vout = NULL;
173 /* We poll the lircsocket */
174 if( lirc_nextcode(&code) != 0 )
184 while( !p_intf->b_die
185 && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
189 if( !strcmp( c, "QUIT" ) )
191 p_intf->p_vlc->b_die = VLC_TRUE;
192 vout_OSDMessage( p_intf, _("Quit" ) );
195 else if( !strcmp( c, "VOL_UP" ) )
197 audio_volume_t i_newvol;
198 aout_VolumeUp( p_intf, 1, &i_newvol );
199 vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
201 else if( !strcmp( c, "VOL_DOWN" ) )
203 audio_volume_t i_newvol;
204 aout_VolumeDown( p_intf, 1, &i_newvol );
205 vout_OSDMessage( p_intf, _("Vol %%%d"), i_newvol*100/AOUT_VOLUME_MAX );
207 else if( !strcmp( c, "MUTE" ) )
209 audio_volume_t i_newvol = -1;
210 aout_VolumeMute( p_intf, &i_newvol );
213 vout_OSDMessage( p_intf, _( "Mute" ) );
217 vout_OSDMessage( p_intf, _("Vol %d%%"), i_newvol*100/AOUT_VOLUME_MAX );
222 if( !strcmp( c, "FULLSCREEN" ) )
224 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
227 if( !strcmp( c, "ACTIVATE" ) )
230 val.psz_string = "ENTER";
231 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
233 msg_Warn( p_intf, "key-press failed" );
238 if( !strcmp( c, "LEFT" ) )
241 val.psz_string = "LEFT";
242 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
244 msg_Warn( p_intf, "key-press failed" );
249 if( !strcmp( c, "RIGHT" ) )
252 val.psz_string = "RIGHT";
253 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
255 msg_Warn( p_intf, "key-press failed" );
260 if( !strcmp( c, "UP" ) )
263 val.psz_string = "UP";
264 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
266 msg_Warn( p_intf, "key-press failed" );
271 if( !strcmp( c, "DOWN" ) )
274 val.psz_string = "DOWN";
275 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
277 msg_Warn( p_intf, "key-press failed" );
283 if( !strcmp( c, "PLAY" ) )
285 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
289 vlc_mutex_lock( &p_playlist->object_lock );
290 if( p_playlist->i_size )
292 vlc_mutex_unlock( &p_playlist->object_lock );
293 playlist_Play( p_playlist );
294 vlc_object_release( p_playlist );
300 if( !strcmp( c, "PLAYPAUSE" ) )
303 val.i_int = PLAYING_S;
306 var_Get( p_input, "state", &val );
308 if( p_input && val.i_int != PAUSE_S )
310 vout_OSDMessage( VLC_OBJECT(p_intf), _( "Pause" ) );
312 var_Set( p_input, "state", val );
316 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
320 vlc_mutex_lock( &p_playlist->object_lock );
321 if( p_playlist->i_size )
323 vlc_mutex_unlock( &p_playlist->object_lock );
324 vout_OSDMessage( p_intf, _( "Play" ) );
325 playlist_Play( p_playlist );
326 vlc_object_release( p_playlist );
335 if( !strcmp( c, "AUDIO_TRACK" ) )
337 vlc_value_t val,list,list2;
339 var_Get( p_input, "audio-es", &val );
340 var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES, &list, &list2 );
341 i_count = list.p_list->i_count;
342 for( i = 0; i < i_count; i++ )
344 if( val.i_int == list.p_list->p_values[i].i_int )
349 /* value of audio-es was not in choices list */
352 msg_Warn( p_input, "invalid current audio track, selecting 0" );
353 var_Set( p_input, "audio-es", list.p_list->p_values[0] );
356 else if( i == i_count - 1 )
358 var_Set( p_input, "audio-es", list.p_list->p_values[0] );
363 var_Set( p_input, "audio-es", list.p_list->p_values[i+1] );
366 vout_OSDMessage( VLC_OBJECT(p_input), _("Audio track: %s"), list2.p_list->p_values[i].psz_string );
368 else if( !strcmp( c, "SUBTITLE_TRACK" ) )
370 vlc_value_t val,list,list2;
372 var_Get( p_input, "spu-es", &val );
373 var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, &list, &list2 );
374 i_count = list.p_list->i_count;
375 for( i = 0; i < i_count; i++ )
377 if( val.i_int == list.p_list->p_values[i].i_int )
382 /* value of audio-es was not in choices list */
385 msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
386 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
389 else if( i == i_count - 1 )
391 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
396 var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
399 vout_OSDMessage( VLC_OBJECT(p_input), _("Subtitle track: %s"), list2.p_list->p_values[i].psz_string );
401 else if( !strcmp( c, "PAUSE" ) )
404 vout_OSDMessage( p_intf, _( "Pause" ) );
406 var_Set( p_input, "state", val );
408 else if( !strcmp( c, "NEXT" ) )
410 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
414 playlist_Next( p_playlist );
415 vlc_object_release( p_playlist );
418 else if( !strcmp( c, "PREV" ) )
420 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
424 playlist_Prev( p_playlist );
425 vlc_object_release( p_playlist );
428 else if( !strcmp( c, "STOP" ) )
430 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
434 playlist_Stop( p_playlist );
435 vlc_object_release( p_playlist );
438 else if( !strcmp( c, "FAST" ) )
440 vlc_value_t val; val.b_bool = VLC_TRUE;
441 var_Set( p_input, "rate-faster", val );
443 else if( !strcmp( c, "SLOW" ) )
445 vlc_value_t val; val.b_bool = VLC_TRUE;
446 var_Set( p_input, "rate-slower", val );
448 /* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
449 else if ( !strcmp(c, "CHAPTER_N" ) ||
450 !strcmp( c, "CHAPTER_P" ) )
452 unsigned int i_chapter = 0;
454 if( !strcmp( c, "CHAPTER_N" ) )
456 vlc_mutex_lock( &p_input->stream.stream_lock );
457 i_chapter = p_input->stream.p_selected_area->i_part + 1;
458 vlc_mutex_unlock( &p_input->stream.stream_lock );
460 else if( !strcmp( c, "CHAPTER_P" ) )
462 vlc_mutex_lock( &p_input->stream.stream_lock );
463 i_chapter = p_input->stream.p_selected_area->i_part - 1;
464 vlc_mutex_unlock( &p_input->stream.stream_lock );
467 vlc_mutex_lock( &p_input->stream.stream_lock );
468 if( ( i_chapter > 0 ) && ( i_chapter <
469 p_input->stream.p_selected_area->i_part_nb ) )
471 input_area_t *p_area = p_input->stream.p_selected_area;
472 p_input->stream.p_selected_area->i_part = i_chapter;
473 vlc_mutex_unlock( &p_input->stream.stream_lock );
474 input_ChangeArea( p_input, p_area );
475 input_SetStatus( p_input, INPUT_STATUS_PLAY );
476 vlc_mutex_lock( &p_input->stream.stream_lock );
478 vlc_mutex_unlock( &p_input->stream.stream_lock );
480 /* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */