1 /*****************************************************************************
2 * lirc.c : lirc module for vlc
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
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, SOLO_CHAN, _("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, SOLO_CHAN, _("Vol %%%d"),
200 i_newvol * 100 / AOUT_VOLUME_MAX );
202 else if( !strcmp( c, "VOL_DOWN" ) )
204 audio_volume_t i_newvol;
205 aout_VolumeDown( p_intf, 1, &i_newvol );
206 vout_OSDMessage( p_intf, SOLO_CHAN, _("Vol %%%d"),
207 i_newvol * 100 / AOUT_VOLUME_MAX );
209 else if( !strcmp( c, "MUTE" ) )
211 audio_volume_t i_newvol = -1;
212 aout_VolumeMute( p_intf, &i_newvol );
215 vout_OSDMessage( p_intf, SOLO_CHAN, _( "Mute" ) );
219 vout_OSDMessage( p_intf, SOLO_CHAN, _("Vol %d%%"),
220 i_newvol * 100 / AOUT_VOLUME_MAX );
225 if( !strcmp( c, "FULLSCREEN" ) )
227 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
230 if( !strcmp( c, "ACTIVATE" ) )
233 val.psz_string = "ENTER";
234 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
236 msg_Warn( p_intf, "key-press failed" );
241 if( !strcmp( c, "LEFT" ) )
244 val.psz_string = "LEFT";
245 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
247 msg_Warn( p_intf, "key-press failed" );
252 if( !strcmp( c, "RIGHT" ) )
255 val.psz_string = "RIGHT";
256 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
258 msg_Warn( p_intf, "key-press failed" );
263 if( !strcmp( c, "UP" ) )
266 val.psz_string = "UP";
267 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
269 msg_Warn( p_intf, "key-press failed" );
274 if( !strcmp( c, "DOWN" ) )
277 val.psz_string = "DOWN";
278 if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
280 msg_Warn( p_intf, "key-press failed" );
286 if( !strcmp( c, "PLAY" ) )
288 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
292 playlist_Play( p_playlist );
293 vlc_object_release( p_playlist );
298 if( !strcmp( c, "PLAYPAUSE" ) )
301 val.i_int = PLAYING_S;
304 var_Get( p_input, "state", &val );
306 if( p_input && val.i_int != PAUSE_S )
308 vout_OSDMessage( VLC_OBJECT(p_intf), SOLO_CHAN,
311 var_Set( p_input, "state", val );
315 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
319 vlc_mutex_lock( &p_playlist->object_lock );
320 if( p_playlist->i_size )
322 vlc_mutex_unlock( &p_playlist->object_lock );
323 vout_OSDMessage( p_intf, SOLO_CHAN, _( "Play" ) );
324 playlist_Play( p_playlist );
325 vlc_object_release( p_playlist );
334 if( !strcmp( c, "AUDIO_TRACK" ) )
336 vlc_value_t val, list, list2;
338 var_Get( p_input, "audio-es", &val );
339 var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES,
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 */
353 "invalid current audio track, selecting 0" );
354 var_Set( p_input, "audio-es",
355 list.p_list->p_values[0] );
358 else if( i == i_count - 1 )
360 var_Set( p_input, "audio-es",
361 list.p_list->p_values[0] );
366 var_Set( p_input, "audio-es",
367 list.p_list->p_values[i+1] );
370 vout_OSDMessage( VLC_OBJECT(p_input), SOLO_CHAN,
371 _("Audio track: %s"),
372 list2.p_list->p_values[i].psz_string );
374 else if( !strcmp( c, "SUBTITLE_TRACK" ) )
376 vlc_value_t val, list, list2;
378 var_Get( p_input, "spu-es", &val );
379 var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
381 i_count = list.p_list->i_count;
382 for( i = 0; i < i_count; i++ )
384 if( val.i_int == list.p_list->p_values[i].i_int )
389 /* value of audio-es was not in choices list */
392 msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
393 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
396 else if( i == i_count - 1 )
398 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
403 var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
406 vout_OSDMessage( VLC_OBJECT(p_input), SOLO_CHAN,
407 _("Subtitle track: %s"),
408 list2.p_list->p_values[i].psz_string );
410 else if( !strcmp( c, "PAUSE" ) )
413 vout_OSDMessage( p_intf, SOLO_CHAN, _( "Pause" ) );
415 var_Set( p_input, "state", val );
417 else if( !strcmp( c, "NEXT" ) )
419 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
423 playlist_Next( p_playlist );
424 vlc_object_release( p_playlist );
427 else if( !strcmp( c, "PREV" ) )
429 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
433 playlist_Prev( p_playlist );
434 vlc_object_release( p_playlist );
437 else if( !strcmp( c, "STOP" ) )
439 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
443 playlist_Stop( p_playlist );
444 vlc_object_release( p_playlist );
447 else if( !strcmp( c, "FAST" ) )
449 vlc_value_t val; val.b_bool = VLC_TRUE;
450 var_Set( p_input, "rate-faster", val );
452 else if( !strcmp( c, "SLOW" ) )
454 vlc_value_t val; val.b_bool = VLC_TRUE;
455 var_Set( p_input, "rate-slower", val );
457 /* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
458 else if ( !strcmp(c, "CHAPTER_N" ) ||
459 !strcmp( c, "CHAPTER_P" ) )
461 unsigned int i_chapter = 0;
463 if( !strcmp( c, "CHAPTER_N" ) )
465 var_SetVoid( p_input, "next-chapter" );
467 else if( !strcmp( c, "CHAPTER_P" ) )
469 var_SetVoid( p_input, "prev-chapter" );
472 /* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */